process #9
4
Makefile
4
Makefile
@@ -1,8 +1,10 @@
|
|||||||
SOURCES = src/sched/scheduler.c src/sched/process.c src/mem/heap/kheap.c src/mem/paging/vmm.c src/mem/paging/paging.c src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
SOURCES = src/sched/scheduler.c src/sched/process.c src/mem/heap/kheap.c src/mem/paging/vmm.c src/mem/paging/paging.c src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
||||||
|
|
||||||
|
PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
|
||||||
|
|
||||||
build:
|
build:
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
x86_64-elf-gcc -g -c -Isrc $(SOURCES) -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-omit-frame-pointer -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
|
x86_64-elf-gcc -g -c -Isrc $(SOURCES) $(PROBLEMATIC_FLAGS) -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-omit-frame-pointer -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
|
||||||
objcopy -O elf64-x86-64 -B i386 -I binary zap-light16.psf zap-light16.o
|
objcopy -O elf64-x86-64 -B i386 -I binary zap-light16.psf zap-light16.o
|
||||||
nasm -f elf64 src/idt/idt.S -o idt_stub.o
|
nasm -f elf64 src/idt/idt.S -o idt_stub.o
|
||||||
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
||||||
|
|||||||
20
README.md
20
README.md
@@ -11,18 +11,28 @@ To run it with QEMU, `make run`
|
|||||||
|
|
||||||
The basics that I'm targeting are:
|
The basics that I'm targeting are:
|
||||||
|
|
||||||
|
### Basic utility of what we call a "kernel"
|
||||||
|
|
||||||
- Fix terminal driver (backspace issues, scrolling) OR add Flanterm or equivalent
|
- Fix terminal driver (backspace issues, scrolling) OR add Flanterm or equivalent
|
||||||
- Implement paging / see what Limine does at boot with memory management
|
|
||||||
- Implement tasks, and task switching
|
- Implement tasks, and task switching
|
||||||
- Load an executable
|
- Load an executable
|
||||||
- Scheduler (round-robin using the PIT timer interrupt)
|
- Filesystem (TAR for read-only initfs, then maybe read-write using FAT12/16/32 or easier fs) w/ VFS layer
|
||||||
- Filesystem (TAR for read-only initfs, then maybe read-write using FAT12/16/32
|
|
||||||
- Getting to userspace (syscalls)
|
- Getting to userspace (syscalls)
|
||||||
- Porting musl libc or equivalent
|
- Porting musl libc or equivalent
|
||||||
|
|
||||||
In the future, maybe?
|
### Scalability/maintenance/expansion features
|
||||||
|
|
||||||
- SMP support
|
- Global config header file
|
||||||
|
- Documentation
|
||||||
|
- SOME error handling in functions
|
||||||
|
- Unit tests
|
||||||
|
- Good error codes (like Linux kernel: ENOMEM, ENOENT, ...)
|
||||||
|
- Make the panic function work within itself without dependencies + error message (and still get cpu context?)
|
||||||
|
|
||||||
|
### Optional features
|
||||||
|
|
||||||
|
In the future, maybe?
|
||||||
|
- SMP support (Limine provides functionality to make this easier)
|
||||||
- Parsing the ACPI tables and using them for something
|
- Parsing the ACPI tables and using them for something
|
||||||
- Replacing the PIT timer with APIC
|
- Replacing the PIT timer with APIC
|
||||||
|
|
||||||
|
|||||||
@@ -188,12 +188,14 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
|||||||
case 32:
|
case 32:
|
||||||
//DEBUG("Timer Interrupt");
|
//DEBUG("Timer Interrupt");
|
||||||
ticks++;
|
ticks++;
|
||||||
|
|
||||||
if (ticks % SCHEDULER_QUANTUM == 0)
|
if (ticks % SCHEDULER_QUANTUM == 0)
|
||||||
{
|
{
|
||||||
CLEAR_INTERRUPTS;
|
CLEAR_INTERRUPTS;
|
||||||
scheduler_schedule();
|
scheduler_schedule();
|
||||||
SET_INTERRUPTS;
|
SET_INTERRUPTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send an EOI so that we can continue having interrupts
|
// Send an EOI so that we can continue having interrupts
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ void hcf()
|
|||||||
|
|
||||||
void panic(struct cpu_status_t* ctx)
|
void panic(struct cpu_status_t* ctx)
|
||||||
{
|
{
|
||||||
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m at rip=%p\nSomething went horribly wrong! vect=0x%.2x errcode=0x%x\nrax=%p rbx=%p rcx=%p rdx=%p\nrsi=%p rdi=%p r8=%p r9=%p\nr10=%p r11=%p r12=%p r13=%p\nr14=%p r15=%p\n\nflags=%p\nstack at rbp=%p\nHalting...",
|
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m at rip=%p\nSomething went horribly wrong! vect=0x%.2x errcode=0x%x\n\rrax=%p rbx=%p rcx=%p rdx=%p\n\rrsi=%p rdi=%p r8=%p r9=%p\n\rr10=%p r11=%p r12=%p r13=%p\n\rr14=%p r15=%p\n\n\rflags=%p\n\rstack at rbp=%p\n\rHalting...",
|
||||||
ctx->iret_rip,
|
ctx->iret_rip,
|
||||||
ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi,
|
ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi,
|
||||||
ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags,
|
ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags,
|
||||||
@@ -126,11 +126,6 @@ void kmain()
|
|||||||
|
|
||||||
kheap_init();
|
kheap_init();
|
||||||
|
|
||||||
void* ptr = kmalloc(10); DEBUG("(KMALLOC TEST) Allocated 10 bytes at 0x%p", ptr);
|
|
||||||
void* ptr2 = kmalloc(200); DEBUG("(KMALLOC TEST) Allocated 200 bytes at 0x%p", ptr2);
|
|
||||||
kfree(ptr);
|
|
||||||
void* ptr3 = kmalloc(5); DEBUG("(KMALLOC TEST) Allocated 5 bytes at 0x%p", ptr3);
|
|
||||||
|
|
||||||
vmm_init();
|
vmm_init();
|
||||||
|
|
||||||
struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0);
|
struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0);
|
||||||
|
|||||||
@@ -16,12 +16,24 @@ static uintptr_t end;
|
|||||||
// Kernel root table (level 4)
|
// Kernel root table (level 4)
|
||||||
extern uint64_t *kernel_pml4;
|
extern uint64_t *kernel_pml4;
|
||||||
|
|
||||||
static void kheap_map_page()
|
static void kheap_grow(size_t size)
|
||||||
|
{
|
||||||
|
size_t pages = ALIGN_UP(size + sizeof(struct heap_block_t), PAGE_SIZE) / PAGE_SIZE;
|
||||||
|
|
||||||
|
if (pages == 0) pages = 1;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pages; i++)
|
||||||
|
{
|
||||||
|
kheap_map_page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void kheap_map_page()
|
||||||
{
|
{
|
||||||
uintptr_t phys = pmm_alloc();
|
uintptr_t phys = pmm_alloc();
|
||||||
paging_map_page(kernel_pml4, end, phys, PTE_PRESENT | PTE_WRITABLE | PTE_NOEXEC);
|
paging_map_page(kernel_pml4, end, phys, PTE_PRESENT | PTE_WRITABLE | PTE_NOEXEC);
|
||||||
end += PAGE_SIZE;
|
end += PAGE_SIZE;
|
||||||
DEBUG("Mapped first kheap page");
|
//DEBUG("Mapped first kheap page");
|
||||||
}
|
}
|
||||||
|
|
||||||
void kheap_init()
|
void kheap_init()
|
||||||
@@ -44,6 +56,7 @@ void* kmalloc(size_t size)
|
|||||||
{
|
{
|
||||||
// No size, no memory allocated!
|
// No size, no memory allocated!
|
||||||
if (!size) return NULL;
|
if (!size) return NULL;
|
||||||
|
size = ALIGN(size);
|
||||||
|
|
||||||
struct heap_block_t* curr = head;
|
struct heap_block_t* curr = head;
|
||||||
|
|
||||||
@@ -53,17 +66,16 @@ void* kmalloc(size_t size)
|
|||||||
if (curr->free && curr->size >= size)
|
if (curr->free && curr->size >= size)
|
||||||
{
|
{
|
||||||
// We split the block if it is big enough
|
// We split the block if it is big enough
|
||||||
if (curr->size > size + sizeof(struct heap_block_t))
|
if (curr->size >= size + BLOCK_MIN_SIZE)
|
||||||
{
|
{
|
||||||
struct heap_block_t* new_block = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
|
//struct heap_block_t* new_block = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
|
||||||
// We have to subtract the size of our block struct
|
struct heap_block_t* split = (struct heap_block_t*)((uintptr_t)curr + sizeof(*curr) + size);
|
||||||
new_block->size = curr->size - size - sizeof(struct heap_block_t);
|
|
||||||
new_block->free = true;
|
|
||||||
|
|
||||||
// Then we chain up the block in the list
|
split->size = curr->size - size - sizeof(*curr);
|
||||||
new_block->next = curr->next;
|
split->free = true;
|
||||||
curr->next = new_block;
|
split->next = curr->next;
|
||||||
|
|
||||||
|
curr->next = split;
|
||||||
curr->size = size;
|
curr->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,14 +87,14 @@ void* kmalloc(size_t size)
|
|||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're hear it means we didn't have enough memory
|
// If we're here it means we didn't have enough memory
|
||||||
// for the block allocation. So we will allocate more..
|
// for the block allocation. So we will allocate more..
|
||||||
uintptr_t old_end = end;
|
uintptr_t old_end = end;
|
||||||
kheap_map_page();
|
kheap_grow(size + sizeof(struct heap_block_t));
|
||||||
|
|
||||||
struct heap_block_t* block = (struct heap_block_t*)old_end;
|
struct heap_block_t* block = (struct heap_block_t*)old_end;
|
||||||
block->size = PAGE_SIZE - sizeof(struct heap_block_t);
|
block->size = ALIGN_UP(end - old_end - sizeof(struct heap_block_t), 16);
|
||||||
block->free = false;
|
block->free = true;
|
||||||
block->next = NULL;
|
block->next = NULL;
|
||||||
|
|
||||||
// Put the block at the end of the list
|
// Put the block at the end of the list
|
||||||
@@ -93,7 +105,7 @@ void* kmalloc(size_t size)
|
|||||||
}
|
}
|
||||||
curr->next = block;
|
curr->next = block;
|
||||||
|
|
||||||
return (void*)((uintptr_t)block + sizeof(struct heap_block_t));
|
return kmalloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kfree(void* ptr)
|
void kfree(void* ptr)
|
||||||
@@ -104,12 +116,25 @@ void kfree(void* ptr)
|
|||||||
// Set it free!
|
// Set it free!
|
||||||
struct heap_block_t* block = (struct heap_block_t*)((uintptr_t)ptr - sizeof(struct heap_block_t));
|
struct heap_block_t* block = (struct heap_block_t*)((uintptr_t)ptr - sizeof(struct heap_block_t));
|
||||||
block->free = true;
|
block->free = true;
|
||||||
|
|
||||||
|
// merge adjacent free blocks (coalescing)
|
||||||
|
struct heap_block_t* curr = head;
|
||||||
|
while (curr && curr->next)
|
||||||
|
{
|
||||||
|
if (curr->free && curr->next->free)
|
||||||
|
{
|
||||||
|
curr->size += sizeof(*curr) + curr->next->size;
|
||||||
|
curr->next = curr->next->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should alloc enough for a stack (at least 64kb) to be used for a process.
|
// Should alloc enough for a stack (at least 64kb) to be used for a process.
|
||||||
// Should return a pointer to top of the stack (as stack grows DOWNWARDS)
|
// Should return a pointer to top of the stack (as stack grows DOWNWARDS)
|
||||||
void* kalloc_stack()
|
void* kalloc_stack()
|
||||||
{
|
{
|
||||||
void* ptr = kmalloc(PROCESS_STACK_SIZE);
|
uint8_t* ptr = kmalloc(PROCESS_STACK_SIZE);
|
||||||
return ptr+PROCESS_STACK_SIZE;
|
return ptr ? ptr+PROCESS_STACK_SIZE : NULL;
|
||||||
}
|
}
|
||||||
@@ -23,5 +23,6 @@ void kheap_init();
|
|||||||
void* kmalloc(size_t size);
|
void* kmalloc(size_t size);
|
||||||
void kfree(void* ptr);
|
void kfree(void* ptr);
|
||||||
void* kalloc_stack();
|
void* kalloc_stack();
|
||||||
|
void kheap_map_page();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -69,7 +69,7 @@ void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_
|
|||||||
root_table[pml4_i] = VIRT_TO_PHYS(pdpt) | PTE_PRESENT | PTE_WRITABLE;
|
root_table[pml4_i] = VIRT_TO_PHYS(pdpt) | PTE_PRESENT | PTE_WRITABLE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pdpt = (uint64_t *)PHYS_TO_VIRT(root_table[pml4_i] & ~0xFFFULL);
|
pdpt = (uint64_t *)PHYS_TO_VIRT(root_table[pml4_i] & PTE_ADDR_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PDPT: same here
|
// PDPT: same here
|
||||||
@@ -79,7 +79,7 @@ void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_
|
|||||||
pdpt[pdpt_i] = VIRT_TO_PHYS(pd) | PTE_PRESENT | PTE_WRITABLE;
|
pdpt[pdpt_i] = VIRT_TO_PHYS(pd) | PTE_PRESENT | PTE_WRITABLE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pd = (uint64_t *)PHYS_TO_VIRT(pdpt[pdpt_i] & ~0xFFFULL);
|
pd = (uint64_t *)PHYS_TO_VIRT(pdpt[pdpt_i] & PTE_ADDR_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PD: and here
|
// PD: and here
|
||||||
@@ -89,7 +89,7 @@ void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_
|
|||||||
pd[pd_i] = VIRT_TO_PHYS(pt) | PTE_PRESENT | PTE_WRITABLE;
|
pd[pd_i] = VIRT_TO_PHYS(pt) | PTE_PRESENT | PTE_WRITABLE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pt = (uint64_t *)PHYS_TO_VIRT(pd[pd_i] & ~0xFFFULL);
|
pt = (uint64_t *)PHYS_TO_VIRT(pd[pd_i] & PTE_ADDR_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PT: finally, populate the page table entry
|
// PT: finally, populate the page table entry
|
||||||
@@ -102,13 +102,16 @@ void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_
|
|||||||
uint64_t kernel_phys_base;
|
uint64_t kernel_phys_base;
|
||||||
uint64_t kernel_virt_base;
|
uint64_t kernel_virt_base;
|
||||||
|
|
||||||
void paging_init(struct limine_kernel_address_response* kaddr, struct limine_framebuffer* fb)
|
extern struct boot_context boot_ctx;
|
||||||
|
|
||||||
|
void paging_init()
|
||||||
{
|
{
|
||||||
// We should map the kernel, GDT, IDT, stack, framebuffer.
|
// We should map the kernel, GDT, IDT, stack, framebuffer.
|
||||||
// Optionally we could map ACPI tables (we can find them in the Limine memmap)
|
// Optionally we could map ACPI tables (we can find them in the Limine memmap)
|
||||||
|
|
||||||
kernel_phys_base = kaddr->physical_base;
|
kernel_phys_base = boot_ctx.kaddr->physical_base;
|
||||||
kernel_virt_base = kaddr->virtual_base;
|
kernel_virt_base = boot_ctx.kaddr->virtual_base;
|
||||||
|
struct limine_framebuffer* fb = boot_ctx.fb;
|
||||||
|
|
||||||
DEBUG("Kernel lives at virt=0x%p phys=0x%p", kernel_virt_base, kernel_phys_base);
|
DEBUG("Kernel lives at virt=0x%p phys=0x%p", kernel_virt_base, kernel_phys_base);
|
||||||
|
|
||||||
@@ -117,14 +120,38 @@ void paging_init(struct limine_kernel_address_response* kaddr, struct limine_fra
|
|||||||
// for debug
|
// for debug
|
||||||
uint64_t page_count = 0;
|
uint64_t page_count = 0;
|
||||||
|
|
||||||
// HHDM map first 1 GB using given offset
|
// Find max physical address from limine memmap
|
||||||
for (uint64_t i=0; i<0x40000000; i += PAGE_SIZE)
|
uint64_t max_phys = 0;
|
||||||
|
for (uint64_t i=0; i<boot_ctx.mmap->entry_count; i++)
|
||||||
|
{
|
||||||
|
struct limine_memmap_entry* entry = boot_ctx.mmap->entries[i];
|
||||||
|
if (entry->length == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uint64_t top = entry->base + entry->length;
|
||||||
|
if (top > max_phys)
|
||||||
|
{
|
||||||
|
max_phys = top;
|
||||||
|
}
|
||||||
|
//DEBUG("max_phys=0x%p", max_phys);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4GB
|
||||||
|
if (max_phys > 0x100000000)
|
||||||
|
{
|
||||||
|
DEBUG("WARNING: max_phys capped to 4GB (0x100000000) (from max_phys=%p)", max_phys);
|
||||||
|
max_phys = 0x100000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HHDM map up to max_phys or 4GB, whichever is smaller, using given offset
|
||||||
|
for (uint64_t i=0; i<max_phys; i += PAGE_SIZE)
|
||||||
{
|
{
|
||||||
//paging_kmap_page(i+hhdm_off, i, PTE_WRITABLE);
|
//paging_kmap_page(i+hhdm_off, i, PTE_WRITABLE);
|
||||||
paging_map_page(kernel_pml4, i+hhdm_off, i, PTE_WRITABLE);
|
paging_map_page(kernel_pml4, i+hhdm_off, i, PTE_WRITABLE | PTE_PRESENT);
|
||||||
page_count++;
|
page_count++;
|
||||||
}
|
}
|
||||||
DEBUG("Mapped %u pages for first 1GB (HHDM)", page_count); page_count = 0;
|
DEBUG("Mapped %u pages up to 0x%p (HHDM)", page_count, max_phys); page_count = 0;
|
||||||
|
|
||||||
// Map the kernel (according to virt/phys_base given by Limine)
|
// Map the kernel (according to virt/phys_base given by Limine)
|
||||||
// SOME DAY when we want a safer kernel we should map .text as Read/Exec
|
// SOME DAY when we want a safer kernel we should map .text as Read/Exec
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
|
#include "mem/heap/kheap.h"
|
||||||
|
|
||||||
void paging_init(struct limine_kernel_address_response* kaddr, struct limine_framebuffer* fb);
|
void paging_init();
|
||||||
void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_t flags);
|
void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_t flags);
|
||||||
|
|
||||||
extern uint64_t hhdm_off;
|
extern uint64_t hhdm_off;
|
||||||
@@ -15,10 +16,14 @@ extern uint64_t hhdm_off;
|
|||||||
#define PHYS_TO_VIRT(x) ((void*)((uintptr_t)(x) + hhdm_off))
|
#define PHYS_TO_VIRT(x) ((void*)((uintptr_t)(x) + hhdm_off))
|
||||||
#define VIRT_TO_PHYS(x) ((uintptr_t)(x) - hhdm_off)
|
#define VIRT_TO_PHYS(x) ((uintptr_t)(x) - hhdm_off)
|
||||||
|
|
||||||
|
#define PTE_ADDR_MASK 0x000FFFFFFFFFF000
|
||||||
// Stole it
|
// Stole it
|
||||||
#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
|
#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
|
||||||
#define ALIGN_DOWN(x, align) ((x) & ~((align) - 1))
|
#define ALIGN_DOWN(x, align) ((x) & ~((align) - 1))
|
||||||
#define PAGE_ALIGN_DOWN(x) ((x) & ~0xFFFULL)
|
#define PAGE_ALIGN_DOWN(x) ((x) & PTE_ADDR_MASK)
|
||||||
|
|
||||||
|
#define ALIGN(size) ALIGN_UP(size, 16)
|
||||||
|
#define BLOCK_MIN_SIZE (sizeof(struct heap_block_t) + 16)
|
||||||
|
|
||||||
#define PML4_INDEX(x) (((x) >> 39) & 0x1FF)
|
#define PML4_INDEX(x) (((x) >> 39) & 0x1FF)
|
||||||
#define PDPT_INDEX(x) (((x) >> 30) & 0x1FF)
|
#define PDPT_INDEX(x) (((x) >> 30) & 0x1FF)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ typedef enum
|
|||||||
} status_t;
|
} status_t;
|
||||||
|
|
||||||
#define PROCESS_NAME_MAX 64
|
#define PROCESS_NAME_MAX 64
|
||||||
#define PROCESS_STACK_SIZE 0x100 // 64kb
|
#define PROCESS_STACK_SIZE 0x10000 // 64kb
|
||||||
|
|
||||||
struct process_t
|
struct process_t
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user