Merge into main the new state of the operating system/kernel #1
5
Makefile
5
Makefile
@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
|
||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
||||
|
||||
OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o
|
||||
OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o
|
||||
|
||||
SRC_DIR = src
|
||||
BUILD_DIR = build
|
||||
@ -79,3 +79,6 @@ $(BUILD_DIR)/idt.o:
|
||||
|
||||
$(BUILD_DIR)/pic.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/string.o:
|
||||
$(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "MMU.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
@ -34,8 +35,13 @@ void MMU::enable(){
|
||||
enablePaging();
|
||||
}
|
||||
|
||||
|
||||
uint32_t MMU::readTableEntry(int entry){
|
||||
return this->page_directory[entry];
|
||||
|
||||
}
|
||||
/*
|
||||
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
|
||||
{
|
||||
from = from & 0xFFFFF000; // Discard the bits we don't want
|
||||
for (; size > 0; from += 4096, first_pte++)
|
||||
{
|
||||
*first_pte = from | 1; // makr page present.
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -1,14 +1,27 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" void loadPageDirectory (long unsigned int* addr );
|
||||
extern "C" void loadPageDirectory (uint32_t* addr );
|
||||
extern "C" void enablePaging();
|
||||
typedef uintptr_t address_t;
|
||||
|
||||
|
||||
#define KB 1024
|
||||
|
||||
static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page
|
||||
static volatile address_t pmem_stack[MAX_PAGES];
|
||||
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
|
||||
|
||||
|
||||
struct page_directory_entry {};
|
||||
struct page_table_entry{};
|
||||
|
||||
|
||||
|
||||
class MMU {
|
||||
public:
|
||||
void enable ();
|
||||
uint32_t readTableEntry(int);
|
||||
|
||||
|
||||
private:
|
||||
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||
uint32_t first_page_table[1024] __attribute__((aligned(4096)));
|
||||
|
@ -21,7 +21,6 @@ stack_bottom:
|
||||
stack_top:
|
||||
|
||||
.section .text
|
||||
|
||||
/*
|
||||
* Interupt handlers
|
||||
*/
|
||||
@ -469,7 +468,7 @@ loadPageDirectory:
|
||||
.type _start, @function
|
||||
_start:
|
||||
/*Setup the stack pointer to point to the beginning of our stack */
|
||||
/* I believe its a hight address growing down to lower adress for the stack on x86*/
|
||||
/* I believe its a high address growing down to lower adress for the stack on x86*/
|
||||
mov $stack_top, %esp
|
||||
|
||||
/*Reset EFLAGS*/
|
||||
@ -484,6 +483,7 @@ _start:
|
||||
|
||||
call early_main
|
||||
cli
|
||||
|
||||
load_gdt:
|
||||
lgdt gdt
|
||||
|
||||
@ -563,4 +563,4 @@ gdt_kdata:
|
||||
.byte 0b10010010 # 1st flags | type flags
|
||||
.byte 0b11001111 # 2nd flags | limit
|
||||
.byte 0x0 # base
|
||||
gdt_end:
|
||||
gdt_end:
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "gdtc.h"
|
||||
|
||||
#include "../tty/kterm.h"
|
||||
|
||||
gdtEntry_t gdt[3];
|
||||
|
||||
@ -18,8 +18,10 @@ void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access,
|
||||
}
|
||||
|
||||
void setupGdt(){
|
||||
|
||||
printf("setupGdt is called!");
|
||||
gdtPointer.limit = (sizeof(gdtEntry_t) * 3) - 1;
|
||||
gdtPointer.base = &gdt;
|
||||
gdtPointer.base = &gdt;
|
||||
|
||||
gdtSetGate(0, 0, 0, 0, 0);
|
||||
gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <stdint.h>
|
||||
extern "c"{
|
||||
extern "C"{
|
||||
|
||||
typedef struct {
|
||||
uint16_t lLimit;
|
||||
|
@ -44,7 +44,7 @@ void irq_handler (registers regs) {
|
||||
// Keyboard interrupt !!
|
||||
|
||||
int scan;
|
||||
register int i;
|
||||
/*register*/int i;
|
||||
|
||||
// Read scancode
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
extern "C"{
|
||||
#include "../tty/kterm.h"
|
||||
}
|
||||
#define AS_KERNEL() ( kterm_writestring("[KERNEL]:"))
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
@ -6,10 +6,11 @@ ENTRY(_start)
|
||||
kernel image. */
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
||||
loaded at by the bootloader. */
|
||||
. = 1M;
|
||||
|
||||
kernel_begin = .;
|
||||
/* First put the multiboot header, as it is required to be put very early
|
||||
early in the image or the bootloader won't recognize the file format.
|
||||
Next we'll put the .text section. */
|
||||
@ -40,4 +41,7 @@ SECTIONS
|
||||
|
||||
/* The compiler may produce other sections, by default it will put them in
|
||||
a segment with the same name. Simply add stuff here as needed. */
|
||||
}
|
||||
|
||||
kernel_end = .;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ void PIC_sendEOI (unsigned char irq);
|
||||
}
|
||||
|
||||
|
||||
static uint16_t __pic_get_irq_reg(int ocw3);
|
||||
//static uint16_t __pic_get_irq_reg(int ocw3);
|
||||
uint16_t pic_get_irr(void);
|
||||
uint16_t pic_get_isr(void);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "kterm.h"
|
||||
|
||||
static const size_t VGA_WIDTH = 80;
|
||||
static const size_t VGA_HEIGHT = 25;
|
||||
|
||||
@ -201,8 +202,10 @@ void printf ( const char *format, ...) {
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
|
||||
kterm_writestring("Not implemented!!");
|
||||
break;
|
||||
case 'u':
|
||||
break;
|
||||
case 'x':
|
||||
itoa(buf, c, *((int *) arg++));
|
||||
|
||||
|
@ -6,6 +6,10 @@
|
||||
|
||||
#include "../vga/colors.h"
|
||||
#include "../../../io.h"
|
||||
|
||||
|
||||
#include "./../../../../libc/include/string.h"
|
||||
|
||||
void kterm_init();
|
||||
|
||||
/* Kernel terminal - Colour functions*/
|
||||
@ -31,7 +35,7 @@ int get_cursor_y (uint16_t cursor_pos);
|
||||
|
||||
void printf ( const char *format, ...);
|
||||
|
||||
static void itoa (char *buf, int base, int d);
|
||||
//static void itoa (char *buf, int base, int d);
|
||||
|
||||
#define KernelTag "[Kernel]: "
|
||||
#define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
|
||||
|
@ -33,7 +33,7 @@ void CheckMBT ( multiboot_info_t* mbt ){
|
||||
/* Are mods_* valid? */
|
||||
if(CHECK_FLAG ( mbi->flags, 3)){
|
||||
multiboot_module_t *mod;
|
||||
int i;
|
||||
uint32_t i;
|
||||
|
||||
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <cpuid.h> // NOTE: Only available in GCC
|
||||
|
||||
static int get_model(){
|
||||
// NOT currently usefull!
|
||||
/* static int get_model(){
|
||||
int ebx, unused;
|
||||
__cpuid(0, unused, ebx, unused, unused);
|
||||
return ebx;
|
||||
@ -14,3 +14,4 @@
|
||||
__get_cpuid(1, &eax, &unused, &unused, &edx);
|
||||
return edx & CPUID_FEAT_EDX_APIC;
|
||||
}
|
||||
*/
|
17
src/kernel/disk.h
Normal file
17
src/kernel/disk.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
// Let's write an ATA PIO | ATA driver for now. Mostly to show that I can in theory interact with a
|
||||
// storage device
|
||||
|
||||
// PRIMARY_ATA_BUS
|
||||
// 0x1F0 through 0x1F7
|
||||
|
||||
// SECONDARY_ATA_BUS
|
||||
// 0x170 through 0x177
|
||||
|
||||
#define DEVICE_CONTROL_REGISTER 0x3F6
|
||||
#define DEVICE_CONTROL_ALTERNATE 0x376
|
||||
|
||||
|
||||
// IRQ14 Primary bus interrupt
|
||||
// IRQ15 Secondary bus interrupt
|
@ -1,19 +1,24 @@
|
||||
#include "io.h"
|
||||
|
||||
unsigned char inb_p(unsigned short ){
|
||||
|
||||
// TODO: implement me!
|
||||
return 0;
|
||||
}
|
||||
unsigned short inw(unsigned short ){
|
||||
|
||||
// TODO: implement me!
|
||||
return 0;
|
||||
}
|
||||
unsigned short inw_p(unsigned short ){
|
||||
|
||||
// TODO: implement me!
|
||||
return 0;
|
||||
}
|
||||
unsigned int inl(unsigned short ){
|
||||
|
||||
// TODO: implement me!
|
||||
return 0;
|
||||
}
|
||||
unsigned int inl_p(unsigned short ){
|
||||
|
||||
// TODO: implement me!
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,12 +23,21 @@ extern "C" {
|
||||
/* Are mmap_* valid? */
|
||||
if (CHECK_FLAG(mbt->flags, 6)){
|
||||
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
|
||||
|
||||
uint32_t memorySizeInBytes = 0;
|
||||
uint32_t reservedMemoryInBytes = 0;
|
||||
|
||||
|
||||
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
|
||||
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
|
||||
|
||||
for (mmap; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
||||
|
||||
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
||||
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
|
||||
memorySizeInBytes += mmap->len;
|
||||
} else {
|
||||
reservedMemoryInBytes += mmap->len;
|
||||
}
|
||||
|
||||
|
||||
printf(
|
||||
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
|
||||
(unsigned) mmap->size,
|
||||
@ -39,37 +48,44 @@ extern "C" {
|
||||
(unsigned) mmap->type);
|
||||
|
||||
}
|
||||
|
||||
uint32_t memorySizeInGiB = memorySizeInBytes / 1073741824;
|
||||
|
||||
printf("Available Memory: 0x%x bytes, 0x%x GiB\n", memorySizeInBytes, memorySizeInGiB );
|
||||
printf("Reserved Memory: 0x%x bytes\n", reservedMemoryInBytes );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//int cpu_model = get_model();
|
||||
//int local_apic = check_apic();
|
||||
//printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic);
|
||||
|
||||
|
||||
/* Setup Paging and memory Managment*/
|
||||
//MMU MemoryManagementUnit = MMU();
|
||||
//MemoryManagementUnit.enable(); // Warning: Causes triple page fault
|
||||
//printf("Pages available: %9d\n", pmm_available());
|
||||
|
||||
/* Draw diagonal blue line */
|
||||
if (CHECK_FLAG (mbi->flags, 12)){
|
||||
if (CHECK_FLAG (mbt->flags, 12)){
|
||||
printf("Can draw!");
|
||||
}
|
||||
|
||||
int cpu_model = get_model();
|
||||
int local_apic = check_apic();
|
||||
printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic);
|
||||
//setupGdt();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void kernel_main (void) {
|
||||
|
||||
init_serial();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
while (true){
|
||||
while (false){
|
||||
//Read time indefinetely
|
||||
read_rtc();
|
||||
printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
extern "C" {
|
||||
#include "../libc/include/string.h"
|
||||
|
||||
#include "arch/i386/tty/kterm.h"
|
||||
#include "pmm.h"
|
||||
}
|
||||
|
||||
#include "../libc/include/string.h"
|
||||
#include "multiboot.h"
|
||||
#include "bootcheck.h"
|
||||
#include "arch/i386/idt/idt.h"
|
||||
|
108
src/kernel/pci.cpp
Normal file
108
src/kernel/pci.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include "pci.h"
|
||||
|
||||
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset){
|
||||
uint32_t address;
|
||||
uint32_t lbus = (uint32_t) bus;
|
||||
uint32_t lslot = (uint32_t) slot;
|
||||
uint32_t lfunc = (uint32_t) func;
|
||||
uint16_t tmp = 0;
|
||||
|
||||
/* Create configuration address as per Figure 1 */
|
||||
address = (uint32_t) ((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) |((uint32_t) 0x80000000) );
|
||||
/*write out the address */
|
||||
outl(CONFIG_ADDRESS, address);
|
||||
/* read in the data */
|
||||
/* (offset & 2 ) * 8 ) = o will choosse the first word of the 32 bits register*/
|
||||
tmp = (uint16_t)((inl(CONFIG_DATA)) >> ((offset & 2) * 8) & 0xFFFF);
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
uint16_t CheckVendor (uint8_t bus, uint8_t slot) {
|
||||
uint16_t vendor, device;
|
||||
/*
|
||||
Try and read the first configuration register. Since there ar no
|
||||
vendors that == 0xFFFF, it must be a non-existent device.
|
||||
*/
|
||||
if((vendor = ConfigReadWord(bus, slot, 0,0)) != 0xFFFF) {
|
||||
device = ConfigReadWord(bus, slot, 0,2);
|
||||
// Possible read more config values ...
|
||||
} return (vendor);
|
||||
}
|
||||
|
||||
void checkDevice (uint8_t bus, uint8_t device ) {
|
||||
uint8_t function = 0;
|
||||
|
||||
uint16_t vendorID = CheckVendor(bus, device);
|
||||
if (vendorID == 0xFFFF) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkFunction (bus, device, function );
|
||||
headerType = getHeaderType(bus, device, function );
|
||||
if( (headerType & 0x80) != 0) {
|
||||
/* It is a multi-function device, so check remaining functions */
|
||||
for (function = 1; function < 8; function++){
|
||||
if (CheckVendor(bus, device)!= 0xFFFF){
|
||||
checkFunction(bus, device, function );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void checkFunction (uint8_t bus, uint8_t device, uint8_t function ){
|
||||
uint8_t baseClass;
|
||||
uint8_t subClass;
|
||||
uint8_t secondaryBus;
|
||||
|
||||
baseClass = getBaseClass(bus, device, function);
|
||||
subClass = getSubClass (bus, device, function );
|
||||
if ( (baseClass == 0x06) && (subClass == 0x04)){
|
||||
secondaryBus = getSecondaryBus(bus,device, function);
|
||||
checkBus(secondaryBus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Brute-force scan
|
||||
void checkAllBuses (){
|
||||
uint16_t bus;
|
||||
uint8_t device;
|
||||
|
||||
for(bus = 0; bus < 256; bus++){
|
||||
for(device = 0; device < 32; device++){
|
||||
checkDevice(bus,device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive scan
|
||||
void checkBus (uint8_t bus){
|
||||
uint8_t device;
|
||||
|
||||
for(device = 0; device < 32; device ++){
|
||||
checkDevice(bus,device);
|
||||
}
|
||||
}
|
||||
|
||||
void checkAllBuses(){
|
||||
uint8_t function;
|
||||
uint8_t bus;
|
||||
|
||||
headerType = getHeaderType(0,0,0);
|
||||
if ( (headerType & 0x80) == 0 ){
|
||||
/* Single PCI host controller */
|
||||
checkBus(0);
|
||||
} else{
|
||||
/* Multiple PCI host controllers */
|
||||
for (function = 0; function < 8; function++){
|
||||
if( CheckVendor(0,0) != 0xFFFF) {
|
||||
break;
|
||||
}
|
||||
bus = function;
|
||||
checkBus(bus);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
58
src/kernel/pci.h
Normal file
58
src/kernel/pci.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "io.h"
|
||||
// Configuration Space Access Mechanism #1
|
||||
#define CONFIG_ADDRESS 0xCF8 // Configuration adress that is to be accessed
|
||||
#define CONFIG_DATA 0xCFC // Will do the actual configuration operation
|
||||
|
||||
/*
|
||||
CONFIG_ADDRESS
|
||||
|
||||
32 bit register
|
||||
|
||||
bit 31 Enable bit (Should CONFIG_DATA be translatedc to configuration cycles)
|
||||
bit 30 - 24 Reserved
|
||||
bit 23 - 16 Bus Number (Choose a specific PCI BUS)
|
||||
bit 15 - 11 Device Number (Selects specific device one the pci bus)
|
||||
bit 10 - 8 Function Number (Selects a specific function in a device)
|
||||
bit 7 - 0 Register Offset (Offset in the configuration space of 256 Bytes ) NOTE: lowest two bits will always be zero
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
PCI Device structure
|
||||
|
||||
Register offset bits 31-24 bits 23-16 bits 15-8 bits 7-0
|
||||
00 00 Device ID <---- Vendor ID <-------
|
||||
01 04 Status <---- Command <-------
|
||||
02 08 Class code Sub class Prog IF Revision ID
|
||||
03 0C BIST Header Type Ltncy Timer Cache line Size
|
||||
04 10 Base address #0 (BAR0)
|
||||
05 14 Base address #1 (BAR1)
|
||||
06 18 Base address #2 (BAR2)
|
||||
07 1C Base address #3 (BAR3)
|
||||
08 20 Base address #4 (BAR4)
|
||||
09 24 Base address #5 (BAR5)
|
||||
0A 28 Cardbus CIS Pointer
|
||||
0B 2C Subsystem ID <------ Subsystem Vendor ID <-------
|
||||
0C 30 Expansion ROM base address
|
||||
0D 34 Reserved <------- Capabilities Pointer <------
|
||||
0E 38 Reserved <------- <-------- <--------
|
||||
0F 3C Max ltncy Min Grant Interrupt PIN Interrupt Line
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
The idea for now is to support the minimal things necessary to find ATA supported drives
|
||||
*/
|
||||
|
||||
|
||||
// Lets write some boiler plate configuration code
|
||||
|
||||
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
|
||||
|
||||
uint16_t CheckVendor (uint8_t bus, uint8_t slot);
|
||||
|
||||
void checkDevice (uint8_t bus, uint8_t device );
|
1
src/kernel/pmm.cpp
Normal file
1
src/kernel/pmm.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "pmm.h"
|
125
src/kernel/pmm.h
Normal file
125
src/kernel/pmm.h
Normal file
@ -0,0 +1,125 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
// Lets assume we have 2 gigabytes of memory
|
||||
// NOTE: We should really detect how much memory we have
|
||||
#define KiloByte 1024 // bytes
|
||||
#define MegaByte 1048576 // bytes
|
||||
#define GigaByte 1073741824 // bytes
|
||||
#define MemorySize 2147483648 // bytes
|
||||
|
||||
const uint32_t bitmapSize = MemorySize / 8;
|
||||
|
||||
extern void *kernel_begin;
|
||||
extern void *kernel_end;
|
||||
struct __attribute__((packed)) PMSegment {
|
||||
void* address;
|
||||
uint32_t size;
|
||||
PMSegment* Next;
|
||||
};
|
||||
|
||||
|
||||
static PMSegment pmStart;
|
||||
static uint32_t AvailablePhysicalMemory;
|
||||
static uint32_t AllocatedMemorySize;
|
||||
|
||||
void initPhysicalMemoryManager(){
|
||||
AvailablePhysicalMemory = MemorySize;
|
||||
AllocatedMemorySize = 0;
|
||||
|
||||
// Map the kernel
|
||||
PMSegment KernelSegment = PMSegment();
|
||||
printf("end of kernel: 0x%x\n", &kernel_end);
|
||||
printf("start of kernel: 0x%x\n", &kernel_begin);
|
||||
printf("pointer to kernel: 0x%x\n", &KernelSegment);
|
||||
|
||||
pmStart = KernelSegment;
|
||||
KernelSegment.address = kernel_begin;
|
||||
KernelSegment.size = &kernel_end - &kernel_begin;
|
||||
AllocatedMemorySize += KernelSegment.size;
|
||||
KernelSegment.Next = 0;
|
||||
|
||||
// make sure We allocate space for ourselves
|
||||
/*PMSegment start = PMSegment();
|
||||
start.address = KernelSegment.address + KernelSegment.size ;
|
||||
start.size = (MemorySize / sizeof(PMSegment) ) + sizeof (uint32_t) * 2;
|
||||
*/
|
||||
|
||||
//KernelSegment.Next = &start;
|
||||
//AllocatedMemorySize += start.size;
|
||||
}
|
||||
|
||||
void printMemorySegments()
|
||||
{
|
||||
printf("Memory Segments:\n");
|
||||
printf( "Start Segment: [addr: 0x%x, size: 0x%x, Next: 0x%x]\n" ,pmStart.address, pmStart.size, pmStart.Next);
|
||||
printf("----------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
void pmem_free (void* address){
|
||||
|
||||
PMSegment* before = 0;
|
||||
PMSegment* current = &pmStart;
|
||||
|
||||
printf("Address of pmStart : 0x%x\n", pmStart);
|
||||
printf("Looking for segment with address: 0x%x \n", address );
|
||||
printf("Address of pmStart(a.k.a current) : 0x%x \n", current);
|
||||
while( current )
|
||||
{
|
||||
//printf("address of current segment 0x%x\n", current->address );
|
||||
if ( current->address == address ) {
|
||||
// this is the address we want to free
|
||||
printf("Segment found!! Segment address: 0x%x \n", current->address);
|
||||
if ( current->Next && before ){
|
||||
before->Next = current->Next;
|
||||
}else{
|
||||
before->Next = 0;
|
||||
}
|
||||
// TODO: Clean memory [ Something like memset to zeroes]
|
||||
printf("Removing segment of size: 0x%x\n", current->size);
|
||||
AllocatedMemorySize -= current->size;
|
||||
break;
|
||||
}
|
||||
|
||||
before = current;
|
||||
current = current->Next;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void* pmem_alloc ( uint32_t size ){
|
||||
// Get the last segment
|
||||
PMSegment* lastSegment = &pmStart;
|
||||
|
||||
while (lastSegment ) {
|
||||
if( lastSegment->Next == 0){
|
||||
break;
|
||||
}
|
||||
lastSegment = lastSegment->Next;
|
||||
}
|
||||
|
||||
printf("LastSegment is for address: 0x%x\n", lastSegment->address);
|
||||
|
||||
|
||||
// So now we have the last segment available
|
||||
PMSegment newSegment = PMSegment();
|
||||
newSegment.address = (PMSegment*)((uint32_t)lastSegment->address + lastSegment->size +1);
|
||||
|
||||
printf("NewSegment for Address: 0x%x\n", newSegment.address);
|
||||
|
||||
newSegment.size = size;
|
||||
|
||||
lastSegment->Next = &newSegment;
|
||||
|
||||
if ( AllocatedMemorySize + newSegment.size > AvailablePhysicalMemory){
|
||||
// No segment available of this size
|
||||
/// ERROR!!
|
||||
return 0;
|
||||
}
|
||||
AllocatedMemorySize += newSegment.size;
|
||||
|
||||
return newSegment.address;
|
||||
|
||||
|
||||
}
|
@ -49,6 +49,8 @@ void read_rtc() {
|
||||
year = get_RTC_register(0x09);
|
||||
if(century_register != 0) {
|
||||
century = get_RTC_register(century_register);
|
||||
} else {
|
||||
century = 21;
|
||||
}
|
||||
|
||||
do {
|
||||
@ -141,7 +143,7 @@ void WriteTOCMOS(unsigned char array[])
|
||||
asm("cli\n\t" // Clear interrupts
|
||||
"mov al,index\n\t" // move index address
|
||||
"out 0x70,al\n\t" // copy address to CMOS register
|
||||
/* some kind of real delay here is probably best
|
||||
// some kind of real delay here is probably best
|
||||
"mov al,tvalue\n\t" // move value to al
|
||||
"out 0x71,al\n\t" // write 1 byte to CMOS
|
||||
"sti\n\\t" ); // Enable interrupts
|
||||
|
9
src/libc/include/string.c
Normal file
9
src/libc/include/string.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "string.h"
|
||||
|
||||
size_t strlen(const char* str) {
|
||||
size_t len = 0;
|
||||
while(str[len]){
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
@ -1,8 +1,3 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
size_t strlen(const char* str){
|
||||
size_t len = 0;
|
||||
while(str[len]){
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
size_t strlen(const char* str);
|
||||
|
Loading…
Reference in New Issue
Block a user