aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/fs/elf.c18
-rw-r--r--src/kernel/kernel.c3
-rw-r--r--src/kernel/lib/lib.h2
-rw-r--r--src/kernel/lib/memory.c2
-rw-r--r--src/kernel/memory/alloc.h2
-rw-r--r--src/kernel/memory/paging.c73
-rw-r--r--src/kernel/memory/paging.h17
-rw-r--r--src/kernel/system.h2
-rw-r--r--src/kernel/tasks/process.c2
-rw-r--r--src/kernel/tasks/process.h2
10 files changed, 73 insertions, 50 deletions
diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c
index 22cdb74..fe180c4 100644
--- a/src/kernel/fs/elf.c
+++ b/src/kernel/fs/elf.c
@@ -25,7 +25,8 @@ int is_elf(struct elf_header *header)
struct process *elf_load(char *path)
{
- struct page_dir *prev_dir;
+ log("ELF START");
+ u32 *prev_dir;
if (current_proc)
prev_dir = current_proc->cr3;
else
@@ -51,11 +52,12 @@ struct process *elf_load(char *path)
strcpy(proc->name, path);
proc->registers.eip = header->entry;
- log("1");
paging_switch_directory(proc->cr3);
- log("2");
- u32 stk = (u32)malloc(PAGE_SIZE);
- log("3");
+ if (!memory_init())
+ paging_set_present(0, memory_get_all() >> 3);
+
+ u32 stk = (u32)valloc(PAGE_SIZE);
+
proc->registers.useresp = 0x40000000 - (PAGE_SIZE / 2);
proc->registers.ebp = proc->registers.useresp;
proc->registers.esp = proc->registers.useresp;
@@ -66,11 +68,14 @@ struct process *elf_load(char *path)
case 0:
break;
case 1: {
- u32 loc = (u32)malloc(PAGE_SIZE);
+ u32 loc = (u32)valloc(PAGE_SIZE);
+ warn("1");
paging_map(loc, program_header->vaddr, PT_USER);
+ warn("2");
memcpy((void *)program_header->vaddr,
((void *)((u32)file) + program_header->offset),
program_header->filesz);
+ warn("3");
if (program_header->filesz > PAGE_SIZE)
panic("ELF binary section too large");
break;
@@ -81,5 +86,6 @@ struct process *elf_load(char *path)
}
paging_switch_directory(prev_dir);
+ log("ELF END");
return proc;
} \ No newline at end of file
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 82937f2..bd22dfc 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -22,8 +22,9 @@
u32 stack_hold;
-void kernel_main(u32 magic, u32 multiboot_address, u32 esp)
+void kernel_main(u32 magic, u32 addr, u32 esp)
{
+ multiboot_address = addr;
stack_hold = esp;
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
diff --git a/src/kernel/lib/lib.h b/src/kernel/lib/lib.h
index 6f2c04d..bdf0794 100644
--- a/src/kernel/lib/lib.h
+++ b/src/kernel/lib/lib.h
@@ -34,7 +34,7 @@ int memcmp(const void *a_ptr, const void *b_ptr, u32 size);
void memory_info_init(struct multiboot_tag_basic_meminfo *tag);
void memory_mmap_init(struct multiboot_tag_mmap *tag);
-int memory_init(u32 multiboot_address);
+int memory_init();
void memory_print();
u32 memory_get_all();
diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c
index 0f3cb34..0519492 100644
--- a/src/kernel/lib/memory.c
+++ b/src/kernel/lib/memory.c
@@ -98,7 +98,7 @@ void memory_mmap_init(struct multiboot_tag_mmap *tag)
total = sum >> 10; // I want kb
}
-int memory_init(u32 multiboot_address)
+int memory_init()
{
int ret = 0;
struct multiboot_tag *tag;
diff --git a/src/kernel/memory/alloc.h b/src/kernel/memory/alloc.h
index 2e8697f..bb3f452 100644
--- a/src/kernel/memory/alloc.h
+++ b/src/kernel/memory/alloc.h
@@ -4,7 +4,7 @@
#include <stdint.h>
void *malloc(u32);
-void *valloc(u32 req_size); // Page-aligned
+void *valloc(u32);
void *realloc(void *, u32);
void *calloc(u32, u32);
void free(void *);
diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c
index c0c1a6a..94b777e 100644
--- a/src/kernel/memory/paging.c
+++ b/src/kernel/memory/paging.c
@@ -4,47 +4,54 @@
#include <stdint.h>
#include <system.h>
-struct page_dir *current_page_directory;
-struct page_dir kernel_page_directory[1024] __attribute__((aligned(4096)));
+u32 *current_page_directory;
+u32 (*current_page_tables)[1024];
+u32 kernel_page_directory[1024] __attribute__((aligned(4096)));
u32 kernel_page_tables[1024][1024] __attribute__((aligned(4096)));
-void paging_init(struct page_dir *dir, int user)
+void paging_init(u32 *dir, u32 tables[1024][1024], int user)
{
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- dir->tables[i][j] =
+ tables[i][j] =
((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0);
}
}
for (u32 i = 0; i < 1024; i++) {
- dir[i] = *(struct page_dir *)(((u32)dir->tables[i]) | PD_RW | PD_PRESENT |
- (user ? PD_USER : 0));
+ dir[i] = ((u32)tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0);
}
}
extern void KERNEL_END();
-void paging_install(u32 multiboot_address)
+void paging_install()
{
- kernel_page_directory->tables = kernel_page_tables;
+ paging_init(kernel_page_directory, kernel_page_tables, 0);
paging_switch_directory(kernel_page_directory);
- paging_init(current_page_directory, 0);
- // if mmap approach didn't work
- if (!memory_init(multiboot_address))
- paging_set_present(0, memory_get_all() >> 3); // /4
- paging_set_used(0, ((u32)KERNEL_END >> 12) + 1); // /4096
+ if (!memory_init())
+ paging_set_present(0, memory_get_all() >> 3);
+ paging_set_used(0, ((u32)KERNEL_END >> 12) + 1);
paging_enable();
log("Installed paging");
+
+ // Test!
+ u32 a = (u32)malloc(4096);
+ u32 b = (u32)malloc(4096);
+ free((void *)b);
+ free((void *)a);
+ u32 c = (u32)malloc(2048);
+ assert(a == c);
+ info("Malloc test succeeded!");
}
-struct page_dir *paging_make_directory(int user)
+u32 *paging_make_directory(int user)
{
- struct page_dir *dir = valloc(1024 * 1024 * 32);
- dir->tables = valloc(1024 * 1024 * 32);
+ u32 *dir = valloc(1024 * 1024 * 32);
+ u32 *tables = valloc(1024 * 1024 * 32);
- paging_init(dir, user);
+ paging_init(dir, tables, user);
return dir;
}
@@ -60,6 +67,7 @@ void paging_disable()
void paging_enable()
{
+ asm("mov %0, %%cr3" ::"r"(current_page_directory));
u32 cr0;
asm("mov %%cr0, %0" : "=r"(cr0));
cr0 |= 0x80000000;
@@ -67,10 +75,11 @@ void paging_enable()
paging_enabled = 1;
}
-void paging_switch_directory(struct page_dir *dir)
+void paging_switch_directory(u32 *dir)
{
+ current_page_tables = dir;
current_page_directory = dir;
- asm("mov %0, %%cr3" ::"r"(dir));
+ asm("mov %0, %%cr3" ::"r"(current_page_directory));
}
void invlpg(u32 addr)
@@ -82,7 +91,7 @@ void paging_map(u32 phy, u32 virt, u16 flags)
{
u32 pdi = virt >> 22;
u32 pti = virt >> 12 & 0x03FF;
- current_page_directory->tables[pdi][pti] = phy | flags;
+ current_page_tables[pdi][pti] = phy | flags;
invlpg(virt);
}
@@ -90,21 +99,21 @@ u32 paging_get_phys(u32 virt)
{
u32 pdi = virt >> 22;
u32 pti = (virt >> 12) & 0x03FF;
- return current_page_directory->tables[pdi][pti] & 0xFFFFF000;
+ return current_page_tables[pdi][pti] & 0xFFFFF000;
}
u16 paging_get_flags(u32 virt)
{
u32 pdi = virt >> 22;
u32 pti = (virt >> 12) & 0x03FF;
- return current_page_directory->tables[pdi][pti] & 0xFFF;
+ return current_page_tables[pdi][pti] & 0xFFF;
}
void paging_set_flag_up(u32 virt, u32 count, u32 flag)
{
u32 page_n = virt / 0x1000;
for (u32 i = page_n; i < page_n + count; i++) {
- current_page_directory->tables[i / 1024][i % 1024] |= flag;
+ current_page_tables[i / 1024][i % 1024] |= flag;
invlpg(i * 0x1000);
}
}
@@ -113,7 +122,7 @@ void paging_set_flag_down(u32 virt, u32 count, u32 flag)
{
u32 page_n = virt / 0x1000;
for (u32 i = page_n; i < page_n + count; i++) {
- current_page_directory->tables[i / 1024][i % 1024] &= ~flag;
+ current_page_tables[i / 1024][i % 1024] &= ~flag;
invlpg(i * 0x1000);
}
}
@@ -138,6 +147,15 @@ void paging_set_free(u32 virt, u32 count)
paging_set_flag_down(virt, count, PT_USED);
}
+void paging_set_user(u32 virt, u32 count)
+{
+ u32 page_n = virt / 0x1000;
+ for (u32 i = page_n; i < page_n + count; i += 1024) {
+ current_page_directory[i / 1024] |= PD_USER;
+ }
+ paging_set_flag_up(virt, count, PT_USER);
+}
+
u32 paging_find_pages(u32 count)
{
u32 continuous = 0;
@@ -145,8 +163,8 @@ u32 paging_find_pages(u32 count)
u32 start_page = 0;
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- if (!(current_page_directory->tables[i][j] & PT_PRESENT) ||
- (current_page_directory->tables[i][j] & PT_USED)) {
+ if (!(current_page_tables[i][j] & PT_PRESENT) ||
+ (current_page_tables[i][j] & PT_USED)) {
continuous = 0;
start_dir = i;
start_page = j + 1;
@@ -165,6 +183,7 @@ u32 paging_alloc_pages(u32 count)
{
u32 ptr = paging_find_pages(count);
paging_set_used(ptr, count);
+ paging_set_user(ptr, count);
return ptr;
}
@@ -173,7 +192,7 @@ u32 paging_get_used_pages()
u32 n = 0;
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- u8 flags = current_page_directory->tables[i][j] & PT_USED;
+ u8 flags = current_page_tables[i][j] & PT_USED;
if (flags == 1)
n++;
}
diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h
index 17dde1d..553c0e6 100644
--- a/src/kernel/memory/paging.h
+++ b/src/kernel/memory/paging.h
@@ -23,22 +23,16 @@
#define PT_GLOBAL 1 << 8
#define PT_USED 1 << 9
-typedef u32 (*page_tables)[1024] __attribute__((aligned(4096)));
-
-struct page_dir {
- page_tables tables;
-};
-
-struct page_dir *current_page_directory;
-struct page_dir kernel_page_directory[1024] __attribute__((aligned(4096)));
+u32 *current_page_directory;
+u32 kernel_page_directory[1024] __attribute__((aligned(4096)));
int paging_enabled;
-void paging_install(u32 multiboot_address);
+void paging_install();
void paging_enable();
void paging_disable();
-struct page_dir *paging_make_directory(int user);
-void paging_switch_directory(struct page_dir *dir);
+u32 *paging_make_directory(int user);
+void paging_switch_directory(u32 *dir);
void paging_map(u32 phy, u32 virt, u16 flags);
u32 paging_get_phys(u32 virt);
@@ -52,6 +46,7 @@ void paging_set_present(u32 virt, u32 count);
void paging_set_absent(u32 virt, u32 count);
void paging_set_used(u32 virt, u32 count);
void paging_set_free(u32 virt, u32 count);
+void paging_set_user(u32 virt, u32 count);
u32 paging_find_pages(u32 count);
u32 paging_alloc_pages(u32 count);
diff --git a/src/kernel/system.h b/src/kernel/system.h
index f9efe94..57a55fe 100644
--- a/src/kernel/system.h
+++ b/src/kernel/system.h
@@ -5,6 +5,8 @@
#include <stddef.h>
#include <stdint.h>
+u32 multiboot_address;
+
/**
* The ASM registers as packed structure
*/
diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c
index f90df89..900d775 100644
--- a/src/kernel/tasks/process.c
+++ b/src/kernel/tasks/process.c
@@ -179,7 +179,7 @@ struct process *process_from_pid(u32 pid)
struct process *process_make_new()
{
debug("Making new process %d", pid);
- struct process *proc = (struct process *)malloc(sizeof(struct process));
+ struct process *proc = (struct process *)valloc(sizeof(struct process));
proc->registers.cs = 0x1B;
proc->registers.ds = 0x23;
proc->registers.ss = 0x23;
diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h
index 92d5ec2..96ef44b 100644
--- a/src/kernel/tasks/process.h
+++ b/src/kernel/tasks/process.h
@@ -13,7 +13,7 @@ struct mmap {
};
struct process {
- struct page_dir *cr3;
+ u32 *cr3;
struct regs registers;
u32 pid;