aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/drivers/cpu.c13
-rw-r--r--kernel/drivers/ide.c20
-rw-r--r--kernel/features/load.c31
-rw-r--r--kernel/features/mm.c8
-rw-r--r--kernel/features/proc.c2
-rw-r--r--kernel/inc/boot.h7
-rw-r--r--kernel/inc/cpu.h2
-rw-r--r--kernel/inc/mm.h2
-rw-r--r--kernel/inc/proc.h3
-rw-r--r--kernel/main.c18
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