...
This commit is contained in:
@@ -2,34 +2,18 @@
|
|||||||
|
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint64_t base_address;
|
|
||||||
size_t length;
|
|
||||||
} memory_region_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
memory_region_t* regions;
|
|
||||||
size_t num_regions;
|
|
||||||
} memory_map_t;
|
|
||||||
|
|
||||||
typedef void (*arch_panic_t)(const char*);
|
typedef void (*arch_panic_t)(const char*);
|
||||||
typedef void (*arch_putchar_t)(char c);
|
typedef void (*arch_putchar_t)(char c);
|
||||||
typedef uint64_t (*arch_page_size_t)();
|
|
||||||
typedef void (*arch_enable_interrupts_t)();
|
typedef void (*arch_enable_interrupts_t)();
|
||||||
typedef void (*arch_disable_interrupts_t)();
|
typedef void (*arch_disable_interrupts_t)();
|
||||||
typedef memory_map_t (*arch_get_memory_map_t)();
|
|
||||||
typedef void (*arch_halt_t)();
|
typedef void (*arch_halt_t)();
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
arch_panic_t panic;
|
arch_panic_t panic;
|
||||||
arch_putchar_t putchar;
|
arch_putchar_t putchar;
|
||||||
arch_page_size_t page_size;
|
|
||||||
arch_enable_interrupts_t enable_interrupts;
|
arch_enable_interrupts_t enable_interrupts;
|
||||||
arch_disable_interrupts_t disable_interrupts;
|
arch_disable_interrupts_t disable_interrupts;
|
||||||
arch_get_memory_map_t get_memory_map;
|
|
||||||
arch_halt_t halt;
|
arch_halt_t halt;
|
||||||
} arch_api_t;
|
} arch_api_t;
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t character;
|
u8 character;
|
||||||
uint8_t color;
|
u8 color;
|
||||||
} vga_char_t;
|
} vga_char_t;
|
||||||
|
|
||||||
static vga_char_t* vga_buffer = (vga_char_t*)0xb8000;
|
static vga_char_t* vga_buffer = (vga_char_t*)0xb8000;
|
||||||
static uint8_t cursor_row = 0;
|
static u8 cursor_row = 0;
|
||||||
static uint8_t cursor_col = 0;
|
static u8 cursor_col = 0;
|
||||||
|
|
||||||
void console_put_char(char c, uint8_t color)
|
void console_put_char(char c, u8 color)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@@ -30,7 +30,7 @@ void console_put_char(char c, uint8_t color)
|
|||||||
}
|
}
|
||||||
case '\t':
|
case '\t':
|
||||||
{
|
{
|
||||||
uint8_t remainder = 4 - (cursor_col % 4);
|
u8 remainder = 4 - (cursor_col % 4);
|
||||||
cursor_col += remainder;
|
cursor_col += remainder;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,5 @@
|
|||||||
|
|
||||||
#define VGA_DEFAULT_COLOR VGA_LIGHT_GRAY | VGA_BLACK << 4
|
#define VGA_DEFAULT_COLOR VGA_LIGHT_GRAY | VGA_BLACK << 4
|
||||||
|
|
||||||
void console_put_char(char character, uint8_t color);
|
void console_put_char(char character, u8 color);
|
||||||
void console_clear();
|
void console_clear();
|
||||||
@@ -26,7 +26,7 @@ void remap_pic()
|
|||||||
outb(PIC2_DATA, 0);
|
outb(PIC2_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_irq_handler(uint8_t irq, irq_handler_t handler)
|
void register_irq_handler(u8 irq, irq_handler_t handler)
|
||||||
{
|
{
|
||||||
if (irq >= 16)
|
if (irq >= 16)
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@ void register_irq_handler(uint8_t irq, irq_handler_t handler)
|
|||||||
|
|
||||||
void handle_irq(const isr_frame_t* frame)
|
void handle_irq(const isr_frame_t* frame)
|
||||||
{
|
{
|
||||||
uint8_t irq = frame->int_no - 32;
|
u8 irq = frame->int_no - 32;
|
||||||
|
|
||||||
if (irq_handlers[irq])
|
if (irq_handlers[irq])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ typedef void (*irq_handler_t)(const isr_frame_t*);
|
|||||||
|
|
||||||
void remap_pic();
|
void remap_pic();
|
||||||
void handle_irq(const isr_frame_t* frame);
|
void handle_irq(const isr_frame_t* frame);
|
||||||
void register_irq_handler(uint8_t irq, irq_handler_t handler);
|
void register_irq_handler(u8 irq, irq_handler_t handler);
|
||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
|
u64 r15, r14, r13, r12, r11, r10, r9, r8;
|
||||||
uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
|
u64 rbp, rdi, rsi, rdx, rcx, rbx, rax;
|
||||||
uint64_t int_no;
|
u64 int_no;
|
||||||
uint64_t err_code;
|
u64 err_code;
|
||||||
uint64_t rip, cs, rflags, rsp, ss;
|
u64 rip, cs, rflags, rsp, ss;
|
||||||
} __attribute__((packed)) isr_frame_t;
|
} __attribute__((packed)) isr_frame_t;
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
|
#include "arch.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "interrupts/idt.h"
|
#include "interrupts/idt.h"
|
||||||
#include "interrupts/irq.h"
|
#include "interrupts/irq.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "memory/mmap.h"
|
#include "mem.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
void x86_64_main(uint32_t magic, multiboot_info_t* info)
|
void x86_64_main(u32 magic, multiboot_info_t* info)
|
||||||
{
|
{
|
||||||
console_clear();
|
console_clear();
|
||||||
|
|
||||||
@@ -21,28 +22,20 @@ void x86_64_main(uint32_t magic, multiboot_info_t* info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
idt_init();
|
idt_init();
|
||||||
|
|
||||||
|
mem_init(info);
|
||||||
|
|
||||||
remap_pic();
|
remap_pic();
|
||||||
map_memory(info);
|
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
kernel_main();
|
kernel_main();
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_console_putchar(char c)
|
void console_putchar(char c)
|
||||||
{
|
{
|
||||||
console_put_char(c, VGA_DEFAULT_COLOR);
|
console_put_char(c, VGA_DEFAULT_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t arch_page_size()
|
|
||||||
{
|
|
||||||
return 4096;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_api_t arch_api = {
|
arch_api_t arch_api = {
|
||||||
.panic = panic,
|
.putchar = console_putchar,
|
||||||
.putchar = arch_console_putchar,
|
|
||||||
.page_size = arch_page_size,
|
|
||||||
.enable_interrupts = enable_interrupts,
|
|
||||||
.disable_interrupts = disable_interrupts,
|
|
||||||
.get_memory_map = get_memory_map,
|
|
||||||
.halt = halt,
|
.halt = halt,
|
||||||
};
|
};
|
||||||
134
src/arch/x86_64/mem.c
Normal file
134
src/arch/x86_64/mem.c
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#include "mem.h"
|
||||||
|
#include "x86_64/panic.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u64 base_address;
|
||||||
|
size_t length;
|
||||||
|
} memory_region_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
memory_region_t* regions;
|
||||||
|
size_t num_regions;
|
||||||
|
} memory_map_t;
|
||||||
|
|
||||||
|
#define USABLE_REGION_SIZE 32
|
||||||
|
|
||||||
|
static memory_region_t usable_regions[USABLE_REGION_SIZE];
|
||||||
|
static size_t num_regions = 0;
|
||||||
|
|
||||||
|
#define BITMAP_SIZE 32768 // Supports up to 1GB of RAM
|
||||||
|
#define USABLE_REGION_SIZE 32
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
static u8 page_bitmap[BITMAP_SIZE];
|
||||||
|
static u64 total_pages = 0;
|
||||||
|
static u64 free_pages = 0;
|
||||||
|
|
||||||
|
void mem_init(multiboot_info_t* info)
|
||||||
|
{
|
||||||
|
if (!(info->flags & (1 << 6)))
|
||||||
|
{
|
||||||
|
panic("Invalid memory map given by bootloader\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 offset = 0;
|
||||||
|
while (offset < info->mmap_length)
|
||||||
|
{
|
||||||
|
multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(info->mmap_addr + offset);
|
||||||
|
|
||||||
|
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||||
|
{
|
||||||
|
if (num_regions < USABLE_REGION_SIZE)
|
||||||
|
{
|
||||||
|
usable_regions[num_regions] = (memory_region_t){
|
||||||
|
.base_address = mmmt->addr,
|
||||||
|
.length = mmmt->len,
|
||||||
|
};
|
||||||
|
|
||||||
|
num_regions++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("System has more memory than the memory map can hold\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += mmmt->size + sizeof(mmmt->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(page_bitmap, 0xFF, BITMAP_SIZE);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_regions; i++)
|
||||||
|
{
|
||||||
|
memory_region_t region = usable_regions[i];
|
||||||
|
|
||||||
|
u64 start_page = region.base_address / PAGE_SIZE;
|
||||||
|
u64 num_pages = region.length / PAGE_SIZE;
|
||||||
|
|
||||||
|
for (u64 page = start_page; page < start_page + num_pages; page++)
|
||||||
|
{
|
||||||
|
if (page < BITMAP_SIZE * 8)
|
||||||
|
{
|
||||||
|
page_bitmap[page / 8] &= ~(1 << (page % 8));
|
||||||
|
free_pages++;
|
||||||
|
total_pages++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("System has more ram than the bitmap allows!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserve first 64MB which is reserved by boot code
|
||||||
|
// todo(nub31): Later we should only identity map only the kernel pages or make a higher half kernel
|
||||||
|
for (u64 page = 0; page < (64 * 1024 * 1024) / PAGE_SIZE; page++)
|
||||||
|
{
|
||||||
|
if (page < BITMAP_SIZE * 8)
|
||||||
|
{
|
||||||
|
if (!(page_bitmap[page / 8] & (1 << (page % 8))))
|
||||||
|
{
|
||||||
|
page_bitmap[page / 8] |= (1 << (page % 8));
|
||||||
|
free_pages--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 mem_alloc_physical_page()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < BITMAP_SIZE; i++)
|
||||||
|
{
|
||||||
|
if (page_bitmap[i] != 0xFF)
|
||||||
|
{
|
||||||
|
for (int bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (!(page_bitmap[i] & (1 << bit)))
|
||||||
|
{
|
||||||
|
page_bitmap[i] |= (1 << bit);
|
||||||
|
free_pages--;
|
||||||
|
return ((i * 8 + bit) * PAGE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mem_free_physical_page(u64 address)
|
||||||
|
{
|
||||||
|
u64 page = address / PAGE_SIZE;
|
||||||
|
if (page < BITMAP_SIZE * 8)
|
||||||
|
{
|
||||||
|
if (page_bitmap[page / 8] & (1 << (page % 8)))
|
||||||
|
{
|
||||||
|
page_bitmap[page / 8] &= ~(1 << (page % 8));
|
||||||
|
free_pages++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/arch/x86_64/mem.h
Normal file
9
src/arch/x86_64/mem.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "std.h"
|
||||||
|
#include "x86_64/multiboot.h"
|
||||||
|
|
||||||
|
void mem_init(multiboot_info_t* info);
|
||||||
|
|
||||||
|
u64 mem_alloc_physical_page();
|
||||||
|
void mem_free_physical_page(u64 address);
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#include "mmap.h"
|
|
||||||
#include "../panic.h"
|
|
||||||
|
|
||||||
#define USABLE_REGION_SIZE 32
|
|
||||||
|
|
||||||
static memory_region_t usable_regions[USABLE_REGION_SIZE];
|
|
||||||
static size_t num_regions = 0;
|
|
||||||
|
|
||||||
void map_memory(multiboot_info_t* info)
|
|
||||||
{
|
|
||||||
if (!(info->flags & (1 << 6)))
|
|
||||||
{
|
|
||||||
panic("Invalid memory map given by bootloader\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t offset = 0;
|
|
||||||
while (offset < info->mmap_length)
|
|
||||||
{
|
|
||||||
multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(info->mmap_addr + offset);
|
|
||||||
|
|
||||||
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE)
|
|
||||||
{
|
|
||||||
if (num_regions < USABLE_REGION_SIZE)
|
|
||||||
{
|
|
||||||
usable_regions[num_regions] = (memory_region_t){
|
|
||||||
.base_address = mmmt->addr,
|
|
||||||
.length = mmmt->len,
|
|
||||||
};
|
|
||||||
|
|
||||||
num_regions++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("System has more memory than the memory map can hold\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += mmmt->size + sizeof(mmmt->size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memory_map_t get_memory_map()
|
|
||||||
{
|
|
||||||
return (memory_map_t){
|
|
||||||
.num_regions = num_regions,
|
|
||||||
.regions = usable_regions,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../multiboot.h"
|
|
||||||
#include "arch.h"
|
|
||||||
|
|
||||||
void map_memory(multiboot_info_t* mbd);
|
|
||||||
memory_map_t get_memory_map();
|
|
||||||
@@ -68,14 +68,14 @@ enum
|
|||||||
CPUID_FEAT_EDX_PBE = 1 << 31
|
CPUID_FEAT_EDX_PBE = 1 << 31
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void outb(uint16_t port, uint8_t val)
|
static inline void outb(u16 port, u8 val)
|
||||||
{
|
{
|
||||||
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t inb(uint16_t port)
|
static inline u8 inb(u16 port)
|
||||||
{
|
{
|
||||||
uint8_t ret;
|
u8 ret;
|
||||||
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -85,22 +85,22 @@ static inline void io_wait()
|
|||||||
outb(0x80, 0);
|
outb(0x80, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpuid(uint32_t code, uint32_t* a, uint32_t* d)
|
static inline void cpuid(u32 code, u32* a, u32* d)
|
||||||
{
|
{
|
||||||
__asm__ volatile("cpuid" : "=a"(*a), "=d"(*d) : "a"(code) : "ecx", "ebx");
|
__asm__ volatile("cpuid" : "=a"(*a), "=d"(*d) : "a"(code) : "ecx", "ebx");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t rdmsr(uint32_t msr)
|
static inline u64 rdmsr(u32 msr)
|
||||||
{
|
{
|
||||||
uint32_t lo, hi;
|
u32 lo, hi;
|
||||||
__asm__ volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr));
|
__asm__ volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr));
|
||||||
return ((uint64_t)hi << 32) | lo;
|
return ((u64)hi << 32) | lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void wrmsr(uint32_t msr, uint64_t value)
|
static inline void wrmsr(u32 msr, u64 value)
|
||||||
{
|
{
|
||||||
uint32_t lo = (uint32_t)value;
|
u32 lo = (u32)value;
|
||||||
uint32_t hi = (uint32_t)(value >> 32);
|
u32 hi = (u32)(value >> 32);
|
||||||
__asm__ volatile("wrmsr" : : "c"(msr), "a"(lo), "d"(hi));
|
__asm__ volatile("wrmsr" : : "c"(msr), "a"(lo), "d"(hi));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "pmm.h"
|
#include "std.h"
|
||||||
|
|
||||||
void kernel_main()
|
void kernel_main()
|
||||||
{
|
{
|
||||||
pmm_init();
|
|
||||||
|
|
||||||
uint64_t page = pmm_alloc_page();
|
|
||||||
printf("page: %u\n", page);
|
|
||||||
printf("Welcome to nub OS :)\n");
|
printf("Welcome to nub OS :)\n");
|
||||||
}
|
}
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
#include "pmm.h"
|
|
||||||
#include "arch.h"
|
|
||||||
|
|
||||||
#define BITMAP_SIZE 32768 // Supports up to 1GB of RAM
|
|
||||||
#define USABLE_REGION_SIZE 32
|
|
||||||
|
|
||||||
static uint8_t page_bitmap[BITMAP_SIZE];
|
|
||||||
static uint64_t total_pages = 0;
|
|
||||||
static uint64_t free_pages = 0;
|
|
||||||
|
|
||||||
void pmm_init()
|
|
||||||
{
|
|
||||||
memory_map_t memory_map = arch_api.get_memory_map();
|
|
||||||
|
|
||||||
memset(page_bitmap, 0xFF, BITMAP_SIZE);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < memory_map.num_regions; i++)
|
|
||||||
{
|
|
||||||
memory_region_t region = memory_map.regions[i];
|
|
||||||
|
|
||||||
uint64_t start_page = region.base_address / arch_api.page_size();
|
|
||||||
uint64_t num_pages = region.length / arch_api.page_size();
|
|
||||||
|
|
||||||
for (uint64_t page = start_page; page < start_page + num_pages; page++)
|
|
||||||
{
|
|
||||||
if (page < BITMAP_SIZE * 8)
|
|
||||||
{
|
|
||||||
page_bitmap[page / 8] &= ~(1 << (page % 8));
|
|
||||||
free_pages++;
|
|
||||||
total_pages++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("System has more ram than the bitmap allows!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reserve first 64MB which is reserved by boot code
|
|
||||||
for (uint64_t page = 0; page < (64 * 1024 * 1024) / arch_api.page_size(); page++)
|
|
||||||
{
|
|
||||||
if (page < BITMAP_SIZE * 8)
|
|
||||||
{
|
|
||||||
if (!(page_bitmap[page / 8] & (1 << (page % 8))))
|
|
||||||
{
|
|
||||||
page_bitmap[page / 8] |= (1 << (page % 8));
|
|
||||||
free_pages--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the address of first free physical page
|
|
||||||
uint64_t pmm_alloc_page()
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < BITMAP_SIZE; i++)
|
|
||||||
{
|
|
||||||
if (page_bitmap[i] != 0xFF)
|
|
||||||
{
|
|
||||||
for (int bit = 0; bit < 8; bit++)
|
|
||||||
{
|
|
||||||
if (!(page_bitmap[i] & (1 << bit)))
|
|
||||||
{
|
|
||||||
page_bitmap[i] |= (1 << bit);
|
|
||||||
free_pages--;
|
|
||||||
return ((i * 8 + bit) * arch_api.page_size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Frees the physical page at the specified address
|
|
||||||
void pmm_free_page(uint64_t addr)
|
|
||||||
{
|
|
||||||
uint64_t page = addr / arch_api.page_size();
|
|
||||||
if (page < BITMAP_SIZE * 8)
|
|
||||||
{
|
|
||||||
if (page_bitmap[page / 8] & (1 << (page % 8)))
|
|
||||||
{
|
|
||||||
page_bitmap[page / 8] &= ~(1 << (page % 8));
|
|
||||||
free_pages++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "std.h"
|
|
||||||
|
|
||||||
void pmm_init();
|
|
||||||
uint64_t pmm_alloc_page();
|
|
||||||
void pmm_free_page(uint64_t addr);
|
|
||||||
@@ -18,29 +18,18 @@ typedef __builtin_va_list va_list;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef unsigned long size_t;
|
typedef unsigned long size_t;
|
||||||
typedef long ptrdiff_t;
|
|
||||||
typedef long intptr_t;
|
|
||||||
typedef unsigned long uintptr_t;
|
typedef unsigned long uintptr_t;
|
||||||
|
|
||||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||||
|
|
||||||
typedef signed char int8_t;
|
typedef unsigned char u8;
|
||||||
typedef unsigned char uint8_t;
|
typedef signed char i8;
|
||||||
typedef signed short int16_t;
|
typedef unsigned short u16;
|
||||||
typedef unsigned short uint16_t;
|
typedef signed short i16;
|
||||||
typedef signed int int32_t;
|
typedef unsigned int u32;
|
||||||
typedef unsigned int uint32_t;
|
typedef signed int i32;
|
||||||
typedef signed long long int64_t;
|
typedef unsigned long long u64;
|
||||||
typedef unsigned long long uint64_t;
|
typedef signed long long i64;
|
||||||
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef int8_t i8;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef int16_t i16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef int32_t i32;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
typedef int64_t i64;
|
|
||||||
|
|
||||||
#define INT8_MIN (-128)
|
#define INT8_MIN (-128)
|
||||||
#define INT8_MAX 127
|
#define INT8_MAX 127
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ void printf(const char* fmt, ...)
|
|||||||
}
|
}
|
||||||
else if (fmt[i] == 'c')
|
else if (fmt[i] == 'c')
|
||||||
{
|
{
|
||||||
char character = (char)va_arg(args, int64_t);
|
char character = (char)va_arg(args, u64);
|
||||||
arch_api.putchar(character);
|
arch_api.putchar(character);
|
||||||
}
|
}
|
||||||
else if (fmt[i] == 'd')
|
else if (fmt[i] == 'd')
|
||||||
{
|
{
|
||||||
int64_t val = va_arg(args, int64_t);
|
u64 val = va_arg(args, u64);
|
||||||
char buf[21];
|
char buf[21];
|
||||||
itoa64(val, buf);
|
itoa64(val, buf);
|
||||||
for (size_t j = 0; buf[j] != '\0'; j++)
|
for (size_t j = 0; buf[j] != '\0'; j++)
|
||||||
@@ -42,7 +42,7 @@ void printf(const char* fmt, ...)
|
|||||||
}
|
}
|
||||||
else if (fmt[i] == 'u')
|
else if (fmt[i] == 'u')
|
||||||
{
|
{
|
||||||
uint64_t val = va_arg(args, uint64_t);
|
u64 val = va_arg(args, u64);
|
||||||
char buf[21];
|
char buf[21];
|
||||||
uitoa64(val, buf);
|
uitoa64(val, buf);
|
||||||
for (size_t j = 0; buf[j] != '\0'; j++)
|
for (size_t j = 0; buf[j] != '\0'; j++)
|
||||||
@@ -52,7 +52,7 @@ void printf(const char* fmt, ...)
|
|||||||
}
|
}
|
||||||
else if (fmt[i] == 'x')
|
else if (fmt[i] == 'x')
|
||||||
{
|
{
|
||||||
uint64_t val = va_arg(args, uint64_t);
|
u64 val = va_arg(args, u64);
|
||||||
char buf[17];
|
char buf[17];
|
||||||
uitoa64_hex(val, buf);
|
uitoa64_hex(val, buf);
|
||||||
for (size_t j = 0; buf[j] != '\0'; j++)
|
for (size_t j = 0; buf[j] != '\0'; j++)
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
void memset(void* destination, uint8_t value, size_t length)
|
void memset(void* destination, u8 value, size_t length)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < length; i++)
|
for (size_t i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
((uint8_t*)destination)[i] = value;
|
((u8*)destination)[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void memcpy(void* destination, void* source, size_t length)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
((u8*)destination)[i] = ((u8*)source)[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
void memset(void* destination, uint8_t value, size_t length);
|
void memset(void* destination, u8 value, size_t length);
|
||||||
|
void memcpy(void* destination, void* source, size_t length);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
int kstrcmp(const char* a, const char* b)
|
int strcmp(const char* a, const char* b)
|
||||||
{
|
{
|
||||||
while ((*a != '\0' && *b != '\0') && *a == *b)
|
while ((*a != '\0' && *b != '\0') && *a == *b)
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@ void reverse(char* str, size_t length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void itoa64(int64_t value, char* buffer)
|
void itoa64(i64 value, char* buffer)
|
||||||
{
|
{
|
||||||
char temp[21];
|
char temp[21];
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
@@ -75,7 +75,7 @@ void itoa64(int64_t value, char* buffer)
|
|||||||
buffer[j] = '\0';
|
buffer[j] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void uitoa64(uint64_t value, char* buffer)
|
void uitoa64(u64 value, char* buffer)
|
||||||
{
|
{
|
||||||
char temp[21];
|
char temp[21];
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
@@ -100,7 +100,7 @@ void uitoa64(uint64_t value, char* buffer)
|
|||||||
buffer[j] = '\0';
|
buffer[j] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void uitoa64_hex(uint64_t value, char* buffer)
|
void uitoa64_hex(u64 value, char* buffer)
|
||||||
{
|
{
|
||||||
const char* digits = "0123456789abcdef";
|
const char* digits = "0123456789abcdef";
|
||||||
char temp[17];
|
char temp[17];
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
int strcmp(const char* a, const char* b);
|
int strcmp(const char* a, const char* b);
|
||||||
void uitoa64(uint64_t value, char* buffer);
|
void reverse(char* str, size_t length);
|
||||||
void itoa64(int64_t value, char* buffer);
|
|
||||||
void uitoa64_hex(uint64_t value, char* buffer);
|
void uitoa64(u64 value, char* buffer);
|
||||||
|
void itoa64(i64 value, char* buffer);
|
||||||
|
void uitoa64_hex(u64 value, char* buffer);
|
||||||
Reference in New Issue
Block a user