diff options
author | Marvin Borner | 2021-04-10 00:26:39 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-10 00:26:39 +0200 |
commit | 9655593d80e23d2ea3c091e3187e8e47b278bc3d (patch) | |
tree | f618723fd9d457147f4663d2d4990f69fabb2d48 /kernel | |
parent | eeb88df1d501ccec4737c18dddb7ca0a1176304f (diff) |
Gave procs own kernel stack (TSS)
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/drivers/cpu.c | 13 | ||||
-rw-r--r-- | kernel/drivers/ide.c | 20 | ||||
-rw-r--r-- | kernel/features/load.c | 31 | ||||
-rw-r--r-- | kernel/features/mm.c | 8 | ||||
-rw-r--r-- | kernel/features/proc.c | 2 | ||||
-rw-r--r-- | kernel/inc/boot.h | 7 | ||||
-rw-r--r-- | kernel/inc/cpu.h | 2 | ||||
-rw-r--r-- | kernel/inc/mm.h | 2 | ||||
-rw-r--r-- | kernel/inc/proc.h | 3 | ||||
-rw-r--r-- | kernel/main.c | 18 |
10 files changed, 84 insertions, 22 deletions
diff --git a/kernel/drivers/cpu.c b/kernel/drivers/cpu.c index 5d53bef..62b0328 100644 --- a/kernel/drivers/cpu.c +++ b/kernel/drivers/cpu.c @@ -91,6 +91,19 @@ void fpu_restore(void) __asm__ volatile("fxrstor (%0)" ::"r"(fpu_state)); } +PROTECTED extern u32 tss_entry; +void tss_set_stack(u32 ss, u32 esp) +{ + assert(tss_entry && ss && esp); + struct { + u32 prev; + u32 esp0; + u32 ss0; + } *tss = (void *)tss_entry; + tss->esp0 = esp; + tss->ss0 = ss; +} + CLEAR static struct cpuid cpuid(u32 code) { u32 a, b, c, d; diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c index f19fe4d..408630d 100644 --- a/kernel/drivers/ide.c +++ b/kernel/drivers/ide.c @@ -6,7 +6,9 @@ #include <fs.h> #include <ide.h> #include <mem.h> +#include <pci.h> #include <print.h> +#include <str.h> PROTECTED static u8 *ide_buf = NULL; @@ -130,11 +132,9 @@ CLEAR static void ata_probe(void) struct ata_data *data = malloc(sizeof(*data)); data->drive = (bus << 1) | drive; - char *str = malloc(40); - for (int j = 0; j < 40; j += 2) { - str[j] = ide_buf[ATA_IDENT_MODEL + j + 1]; - str[j + 1] = ide_buf[ATA_IDENT_MODEL + j]; - } + char *str = zalloc(8); + strlcpy(str, "hd", 8); + str[2] = 'a' + i; dev->name = str; dev->type = DEV_BLOCK; @@ -156,8 +156,18 @@ CLEAR static void ata_probe(void) } } +CLEAR static void ata_find(u32 device, u16 vendor_id, u16 device_id, void *extra) +{ + if ((vendor_id == 0x8086) && (device_id == 0x7010)) { + *((u32 *)extra) = device; + } +} + +static u32 ata_device_pci = 0; CLEAR void ata_install(void) { + pci_scan(&ata_find, -1, &ata_device_pci); + assert(ata_device_pci); ide_buf = zalloc(SECTOR_SIZE); ata_probe(); } diff --git a/kernel/features/load.c b/kernel/features/load.c index df01e04..02c02ae 100644 --- a/kernel/features/load.c +++ b/kernel/features/load.c @@ -145,7 +145,8 @@ res elf_load(const char *name, struct proc *proc) /* } */ // Remap readonly sections - if (!(section.flags & ELF_SECTION_FLAG_WRITE)) { + if (!(section.flags & ELF_SECTION_FLAG_WRITE) && section.addr && + memory_is_user((void *)section.addr)) { struct memory_range range = memory_range_around(section.addr + rand_off, section.size); virtual_remap_readonly(proc->page_dir, range); @@ -158,14 +159,26 @@ res elf_load(const char *name, struct proc *proc) stac(); - // Allocate stack with readonly lower and upper page boundary - u32 stack = PAGE_SIZE + (u32)memory_alloc(proc->page_dir, PROC_STACK_SIZE + 2 * PAGE_SIZE, - MEMORY_USER | MEMORY_CLEAR); - virtual_remap_readonly(proc->page_dir, memory_range(stack - PAGE_SIZE, PAGE_SIZE)); - virtual_remap_readonly(proc->page_dir, memory_range(stack + PROC_STACK_SIZE, PAGE_SIZE)); - - proc->regs.ebp = stack + PROC_STACK_SIZE; - proc->regs.useresp = stack + PROC_STACK_SIZE; + // Allocate user stack with readonly lower and upper page boundary + u32 user_stack = + PAGE_SIZE + (u32)memory_alloc(proc->page_dir, PROC_STACK_SIZE + 2 * PAGE_SIZE, + MEMORY_USER | MEMORY_CLEAR); + virtual_remap_readonly(proc->page_dir, memory_range(user_stack - PAGE_SIZE, PAGE_SIZE)); + virtual_remap_readonly(proc->page_dir, + memory_range(user_stack + PROC_STACK_SIZE, PAGE_SIZE)); + + // Allocate kernel stack with readonly lower and upper page boundary + u32 kernel_stack = + PAGE_SIZE + + (u32)memory_alloc(proc->page_dir, PROC_STACK_SIZE + 2 * PAGE_SIZE, MEMORY_CLEAR); + virtual_remap_readonly(proc->page_dir, memory_range(kernel_stack - PAGE_SIZE, PAGE_SIZE)); + virtual_remap_readonly(proc->page_dir, + memory_range(kernel_stack + PROC_STACK_SIZE, PAGE_SIZE)); + + proc->user_stack = user_stack + PROC_STACK_SIZE; + proc->kernel_stack = kernel_stack + PROC_STACK_SIZE; + proc->regs.ebp = proc->user_stack; + proc->regs.useresp = proc->user_stack; proc->regs.eip = header.entry + rand_off; proc->entry = header.entry + rand_off; diff --git a/kernel/features/mm.c b/kernel/features/mm.c index 466e448..0972ab3 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -677,8 +677,11 @@ void memory_user_hook(void) } } -CLEAR void memory_install(struct mem_info *mem_info, struct vid_info *vid_info) +CLEAR void memory_install(struct boot_info *boot) { + struct mem_info *mem_info = boot->mem; + struct vid_info *vid_info = boot->vid; + for (struct mmap_boot *p = mem_info->start; (u32)(p - mem_info->start) < mem_info->size; p++) { if (p->hbase || !p->acpi || !p->type) @@ -731,6 +734,9 @@ CLEAR void memory_install(struct mem_info *mem_info, struct vid_info *vid_info) MEMORY_NONE); fb_map_buffer(virtual_kernel_dir(), vid_info); + // Map TSS + memory_map_identity(&kernel_dir, memory_range_around(boot->tss, 0x1000), MEMORY_NONE); + // Unmap NULL byte/page struct memory_range zero = memory_range(0, PAGE_SIZE); virtual_free(&kernel_dir, zero); diff --git a/kernel/features/proc.c b/kernel/features/proc.c index 479427c..d5bf2e6 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -54,6 +54,7 @@ HOT FLATTEN void scheduler(struct regs *regs) current = idle_proc; } + tss_set_stack(0x10, PROC(current)->kernel_stack); memory_switch_dir(PROC(current)->page_dir); memcpy(regs, &PROC(current)->regs, sizeof(*regs)); @@ -581,6 +582,7 @@ NORETURN void proc_init(void) // We'll shortly jump to usermode. Clear and protect every secret! memory_user_hook(); + tss_set_stack(0x10, init->kernel_stack); memory_switch_dir(init->page_dir); printf("Jumping to userspace!\n"); diff --git a/kernel/inc/boot.h b/kernel/inc/boot.h index 7f085cd..48ab440 100644 --- a/kernel/inc/boot.h +++ b/kernel/inc/boot.h @@ -35,4 +35,11 @@ struct mem_info { u32 size; }; +struct boot_info { + struct vid_info *vid; + struct mem_info *mem; + u32 tss; + u32 drive; +}; + #endif diff --git a/kernel/inc/cpu.h b/kernel/inc/cpu.h index 7ac6074..3d29e4f 100644 --- a/kernel/inc/cpu.h +++ b/kernel/inc/cpu.h @@ -32,6 +32,8 @@ void cr3_set(u32 cr3); u32 cr4_get(void); void cr4_set(u32 cr4); +void tss_set_stack(u32 ss, u32 esp); + void clac(void); void stac(void); diff --git a/kernel/inc/mm.h b/kernel/inc/mm.h index b82b441..a9524ad 100644 --- a/kernel/inc/mm.h +++ b/kernel/inc/mm.h @@ -141,6 +141,6 @@ res memory_sys_free(struct page_dir *dir, u32 addr) NONNULL; res memory_sys_shaccess(struct page_dir *dir, u32 id, u32 *addr, u32 *size) NONNULL; void memory_user_hook(void); -void memory_install(struct mem_info *mem_info, struct vid_info *vid_info) NONNULL; +void memory_install(struct boot_info *boot) NONNULL; #endif diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h index dcc2eeb..f5dbf1a 100644 --- a/kernel/inc/proc.h +++ b/kernel/inc/proc.h @@ -53,6 +53,9 @@ struct stream { struct proc { u32 pid; u32 entry; + u32 user_stack; + u32 kernel_stack; + char name[64]; char dir[64]; struct stream streams[4]; diff --git a/kernel/main.c b/kernel/main.c index faac719..ab5fde8 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -19,18 +19,24 @@ #include <syscall.h> #include <timer.h> -extern u32 __stack_chk_guard; -u32 __stack_chk_guard; +PROTECTED extern u32 __stack_chk_guard; +PROTECTED u32 __stack_chk_guard; -int kernel_main(struct mem_info *mem_info, struct vid_info *vid_info); // Decl -int kernel_main(struct mem_info *mem_info, struct vid_info *vid_info) +PROTECTED u32 tss_entry = 0; +PROTECTED u32 boot_drive = 0; + +int kernel_main(struct boot_info *boot); // Decl +int kernel_main(struct boot_info *boot) { // Serial connection serial_install(); serial_print("\nKernel was compiled at " __TIME__ " on " __DATE__ "\n"); serial_print("Serial connected.\n"); - memory_install(mem_info, vid_info); + tss_entry = boot->tss; + boot_drive = boot->drive; + + memory_install(boot); memory_switch_dir(virtual_kernel_dir()); cpu_enable_features(); @@ -49,7 +55,7 @@ int kernel_main(struct mem_info *mem_info, struct vid_info *vid_info) rtc_install(); keyboard_install(); mouse_install(); - fb_install(vid_info); + fb_install(boot->vid); /* net_install(); */ // Enable drivers |