start syscalls
This commit is contained in:
parent
ff347e52f7
commit
6302f2ab9c
2
Makefile
2
Makefile
|
@ -20,7 +20,7 @@ ISO := Hazel.iso
|
||||||
CFLAGS := -ffreestanding -Wall -Wextra -Werror -I $(INCLUDEDIR) -I lib
|
CFLAGS := -ffreestanding -Wall -Wextra -Werror -I $(INCLUDEDIR) -I lib
|
||||||
LDFLAGS := -ffreestanding -nostdlib -lgcc -T kernel/kernel.ld
|
LDFLAGS := -ffreestanding -nostdlib -lgcc -T kernel/kernel.ld
|
||||||
QEMUFLAGS := -cdrom $(BUILDDIR)/$(ISO) \
|
QEMUFLAGS := -cdrom $(BUILDDIR)/$(ISO) \
|
||||||
-s \
|
-s -d int \
|
||||||
-m 512M \
|
-m 512M \
|
||||||
-serial stdio
|
-serial stdio
|
||||||
|
|
||||||
|
|
BIN
boot/initrd
BIN
boot/initrd
Binary file not shown.
|
@ -45,6 +45,10 @@ typedef struct {
|
||||||
uint32_t eflags;
|
uint32_t eflags;
|
||||||
} int_stack_frame_t;
|
} int_stack_frame_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
|
||||||
|
} stack_frame_t;
|
||||||
|
|
||||||
void idt_encode_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes);
|
void idt_encode_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,6 +8,7 @@ typedef struct {
|
||||||
uint32_t esp;
|
uint32_t esp;
|
||||||
uint32_t cr3;
|
uint32_t cr3;
|
||||||
uint32_t *next;
|
uint32_t *next;
|
||||||
|
uint32_t eip;
|
||||||
} task_t;
|
} task_t;
|
||||||
|
|
||||||
int task_init(task_t *task, elf_t *elf);
|
int task_init(task_t *task, elf_t *elf);
|
||||||
|
|
|
@ -94,7 +94,8 @@ pit_isr:
|
||||||
extern pit_handler
|
extern pit_handler
|
||||||
call pit_handler
|
call pit_handler
|
||||||
cmp eax, 1
|
cmp eax, 1
|
||||||
jne .ret
|
; jne .ret
|
||||||
|
jmp .ret
|
||||||
|
|
||||||
mov edi, [ctx+28] ; EDI = current task
|
mov edi, [ctx+28] ; EDI = current task
|
||||||
; mov esi, [edi+8] ; ESI = next task
|
; mov esi, [edi+8] ; ESI = next task
|
||||||
|
@ -133,6 +134,25 @@ flush_tss:
|
||||||
ltr [esp+4]
|
ltr [esp+4]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
global syscall_isr
|
||||||
|
syscall_isr:
|
||||||
|
pushad
|
||||||
|
mov ecx, esp
|
||||||
|
sysenter
|
||||||
|
after_syscall:
|
||||||
|
popad
|
||||||
|
iret
|
||||||
|
|
||||||
|
global syscall
|
||||||
|
syscall:
|
||||||
|
imul eax, eax, 4
|
||||||
|
add eax, syscall_table
|
||||||
|
pushad
|
||||||
|
call [eax]
|
||||||
|
popad
|
||||||
|
mov edx, after_syscall
|
||||||
|
sysexit
|
||||||
|
|
||||||
extern exception_handler
|
extern exception_handler
|
||||||
%macro isr_err_stub 1
|
%macro isr_err_stub 1
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
|
@ -247,6 +267,13 @@ global boot_page_tab
|
||||||
align 0x1000
|
align 0x1000
|
||||||
boot_page_tab: times 1024 dd 0
|
boot_page_tab: times 1024 dd 0
|
||||||
|
|
||||||
|
global syscall_table
|
||||||
|
syscall_table:
|
||||||
|
dd 0
|
||||||
|
|
||||||
|
extern syscall_write
|
||||||
|
dd syscall_write
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
align 16
|
align 16
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
|
@ -19,10 +19,16 @@ extern void pit_isr(void);
|
||||||
extern void jmp_user_mode(uint32_t esp, uint32_t eip);
|
extern void jmp_user_mode(uint32_t esp, uint32_t eip);
|
||||||
extern void flush_tss(uint32_t segment_selector);
|
extern void flush_tss(uint32_t segment_selector);
|
||||||
extern void task_switch(task_t *task);
|
extern void task_switch(task_t *task);
|
||||||
|
extern void syscall(void);
|
||||||
|
extern void syscall_isr(void);
|
||||||
extern gdt_t gdt[6];
|
extern gdt_t gdt[6];
|
||||||
extern uint32_t boot_page_dir[1024];
|
extern uint32_t boot_page_dir[1024];
|
||||||
extern uint32_t boot_page_tab[1024];
|
extern uint32_t boot_page_tab[1024];
|
||||||
|
|
||||||
|
void syscall_write(stack_frame_t r) {
|
||||||
|
LOG("SYSCALL %08X\n", r.eax);
|
||||||
|
}
|
||||||
|
|
||||||
void exception_handler(int_stack_frame_t r) {
|
void exception_handler(int_stack_frame_t r) {
|
||||||
LOG("Exception 0x%X (0x%X) has occurred\nEAX: 0x%08X\nECX: 0x%08X\nEDX: 0x%08X\nEBX: 0x%08X\nESI: 0x%08X\nEDI: 0x%08X\nEBP: 0x%08X\nESP: 0x%08X\n",
|
LOG("Exception 0x%X (0x%X) has occurred\nEAX: 0x%08X\nECX: 0x%08X\nEDX: 0x%08X\nEBX: 0x%08X\nESI: 0x%08X\nEDI: 0x%08X\nEBP: 0x%08X\nESP: 0x%08X\n",
|
||||||
r.int_no, r.err_code, r.eax, r.ecx, r.edx, r.ebx, r.esi, r.edi, r.ebp, r.esp+24);
|
r.int_no, r.err_code, r.eax, r.ecx, r.edx, r.ebx, r.esi, r.edi, r.ebp, r.esp+24);
|
||||||
|
@ -42,6 +48,7 @@ void idt_init(void) {
|
||||||
idt_encode_entry(idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
idt_encode_entry(idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||||
}
|
}
|
||||||
idt_encode_entry(idt, 32, (uint32_t)pit_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), INT_GATE_32 | INT_RING0 | INT_PRESENT);
|
idt_encode_entry(idt, 32, (uint32_t)pit_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), INT_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||||
|
idt_encode_entry(idt, 0x80, (uint32_t)syscall_isr, GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3), INT_GATE_32 | INT_RING3 | INT_PRESENT);
|
||||||
|
|
||||||
idtr.size = (sizeof(struct idt_entry) * 256) - 1;
|
idtr.size = (sizeof(struct idt_entry) * 256) - 1;
|
||||||
idtr.base = (uint32_t) idt;
|
idtr.base = (uint32_t) idt;
|
||||||
|
@ -93,6 +100,7 @@ void kernel(multiboot_info_t *info) {
|
||||||
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(GDT_USER_DATA, RING3);
|
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(GDT_USER_DATA, RING3);
|
||||||
flush_tss(GDT_SEGMENT_SELECTOR(5, RING3));
|
flush_tss(GDT_SEGMENT_SELECTOR(5, RING3));
|
||||||
|
|
||||||
|
/*
|
||||||
task_t task1 = {0};
|
task_t task1 = {0};
|
||||||
task_t task2 = {0};
|
task_t task2 = {0};
|
||||||
task1.cr3 = (uint32_t)boot_page_dir - KERNEL_VMA;
|
task1.cr3 = (uint32_t)boot_page_dir - KERNEL_VMA;
|
||||||
|
@ -115,12 +123,8 @@ void kernel(multiboot_info_t *info) {
|
||||||
task2.esp = (uint32_t)stack + (0x1000 - 44);
|
task2.esp = (uint32_t)stack + (0x1000 - 44);
|
||||||
task2.cr3 = (uint32_t)boot_page_dir - KERNEL_VMA;
|
task2.cr3 = (uint32_t)boot_page_dir - KERNEL_VMA;
|
||||||
task2.next = 0;
|
task2.next = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
LOG("A");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA);
|
multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA);
|
||||||
elf_t *elf = (elf_t *)(init->mod_start+KERNEL_VMA);
|
elf_t *elf = (elf_t *)(init->mod_start+KERNEL_VMA);
|
||||||
task_t task = {0};
|
task_t task = {0};
|
||||||
|
@ -129,9 +133,41 @@ void kernel(multiboot_info_t *info) {
|
||||||
ctx.current_task = &task;
|
ctx.current_task = &task;
|
||||||
asm volatile ("mov %0, %%cr3" :: "r"(task.cr3));
|
asm volatile ("mov %0, %%cr3" :: "r"(task.cr3));
|
||||||
|
|
||||||
|
// Set the ring0 CS
|
||||||
|
asm volatile (
|
||||||
|
"movl $0x174, %%ecx \n\t"
|
||||||
|
"movl %0, %%eax \n\t"
|
||||||
|
"xor %%edx, %%edx \n\t"
|
||||||
|
"wrmsr"
|
||||||
|
:
|
||||||
|
: "r"(GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0))
|
||||||
|
: "eax", "ecx", "edx"
|
||||||
|
);
|
||||||
|
// Set the ring0 stack
|
||||||
|
uint32_t *k_stack = mmap_find_first_free_block();
|
||||||
|
asm volatile (
|
||||||
|
"movl $0x175, %%ecx \n\t"
|
||||||
|
"movl %0, %%eax \n\t"
|
||||||
|
"xor %%edx, %%edx \n\t"
|
||||||
|
"wrmsr"
|
||||||
|
:
|
||||||
|
: "r"((uint32_t)k_stack + 0x1000)
|
||||||
|
: "eax", "ecx", "edx"
|
||||||
|
);
|
||||||
|
// Set the ring0 syscall entry
|
||||||
|
asm volatile (
|
||||||
|
"movl $0x176, %%ecx \n\t" // MSR address
|
||||||
|
"movl %0, %%eax \n\t" // Lower 32 bits (eip)
|
||||||
|
"xor %%edx, %%edx \n\t" // Upper 32 bits (zero for 32-bit value)
|
||||||
|
"wrmsr"
|
||||||
|
:
|
||||||
|
: "r"(syscall)
|
||||||
|
: "eax", "ecx", "edx"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", task.eip, task.esp);
|
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", task.eip, task.esp);
|
||||||
jmp_user_mode(task.esp, task.eip);
|
jmp_user_mode(task.esp, task.eip);
|
||||||
*/
|
|
||||||
|
|
||||||
halt:
|
halt:
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
|
|
|
@ -7,7 +7,7 @@ extern kernel_ctx_t ctx;
|
||||||
int task_init(task_t *task, elf_t *elf) {
|
int task_init(task_t *task, elf_t *elf) {
|
||||||
section_t *text = elf_find_section(elf, ".text");
|
section_t *text = elf_find_section(elf, ".text");
|
||||||
if (!text) return 0;
|
if (!text) return 0;
|
||||||
//task->eip = elf->e_entry + text->sh_offset;
|
task->eip = elf->e_entry + text->sh_offset;
|
||||||
// Allocate a page for a stack
|
// Allocate a page for a stack
|
||||||
task->esp = (uint32_t)mmap_find_first_free_block() + 0x1000;
|
task->esp = (uint32_t)mmap_find_first_free_block() + 0x1000;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ int task_init(task_t *task, elf_t *elf) {
|
||||||
uint32_t *page_tab = mmap_find_first_free_block();
|
uint32_t *page_tab = mmap_find_first_free_block();
|
||||||
for (int i = 0; i < 1024; i++) {
|
for (int i = 0; i < 1024; i++) {
|
||||||
// Map kernel to 3GiB
|
// Map kernel to 3GiB
|
||||||
if (i == 768) page_dir[i] = ((uint32_t)boot_page_tab - KERNEL_VMA) | 3;
|
if (i == 768) page_dir[i] = ((uint32_t)boot_page_tab - KERNEL_VMA) | 7;
|
||||||
// Map 3.4GiB-4GiB as non-present kernel entries
|
// Map 3.4GiB-4GiB as non-present kernel entries
|
||||||
else if (i > 768) page_dir[i] = 4;
|
else if (i > 768) page_dir[i] = 4;
|
||||||
// Map remaining entries as non-present u/s
|
// Map remaining entries as non-present u/s
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
[bits 32]
|
[bits 32]
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
mov eax, 0xDEADBEEF
|
mov ecx, 0xDEADBEEF
|
||||||
|
mov eax, 1
|
||||||
|
int 0x80
|
||||||
jmp $
|
jmp $
|
||||||
|
|
Loading…
Reference in New Issue
Block a user