r/w syscalls and elf init program

This commit is contained in:
rami 2024-07-28 10:11:15 -04:00
parent 6302f2ab9c
commit 4ac1efd433
16 changed files with 685 additions and 297 deletions

View File

@ -1,256 +0,0 @@
ni
ni
c
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
c
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
target remote localhost:1234
target remote localhost:1234
ni
ni
c
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
c
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
c
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni
b pit_isr
c
target remote localhost:1234
c
ni
ni
ni
ni
ni
c
target remote localhost:1234
target remote localhost:1234
c
ni
ni
ni
ni
ni
ni
ni
ni
ni
ni

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
*.iso *.iso
*.bin *.bin
.cache .cache
.gdb_history

View File

@ -1,4 +1,4 @@
CC = i686-elf-gcc CC = /home/rami/crossdev/bin/i686-elf-gcc
AS = nasm AS = nasm
BUILDDIR := build BUILDDIR := build
@ -12,17 +12,14 @@ KIMG := kernel.bin
LSRC := $(wildcard lib/*.c) LSRC := $(wildcard lib/*.c)
LOBJ := $(addprefix $(BUILDDIR)/, \ LOBJ := $(addprefix $(BUILDDIR)/, \
$(notdir \ $(notdir \
$(patsubst %.c,%.o, $(LSRC)))) $(patsubst %.c,%.o, $(LSRC))))
ISO := Hazel.iso 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 -m 512M -serial stdio
-s -d int \
-m 512M \
-serial stdio
$(BUILDDIR)/$(KIMG): $(KOBJ) $(LOBJ) $(BUILDDIR)/$(KIMG): $(KOBJ) $(LOBJ)
$(CC) $^ -o $@ $(LDFLAGS) $(CC) $^ -o $@ $(LDFLAGS)
@ -34,13 +31,16 @@ $(BUILDDIR)/%.o: */%.c
kernel: $(BUILDDIR)/$(KIMG) kernel: $(BUILDDIR)/$(KIMG)
$(BUILDDIR)/$(ISO): kernel $(BUILDDIR)/$(ISO): kernel
rm -f $(BUILDDIR)/$(ISO) boot/initrd make -C user
nasm -felf32 user/userinit.asm -o boot/initrd
cp $(BUILDDIR)/$(KIMG) boot/$(KIMG) cp $(BUILDDIR)/$(KIMG) boot/$(KIMG)
rm -f $(BUILDDIR)/$(ISO)
grub-mkrescue -o $(BUILDDIR)/$(ISO) . grub-mkrescue -o $(BUILDDIR)/$(ISO) .
iso: $(BUILDDIR)/$(ISO) iso: $(BUILDDIR)/$(ISO)
all: iso
qemu: iso qemu: iso
qemu-system-i386 $(QEMUFLAGS) qemu-system-i386 $(QEMUFLAGS)
clean: clean:
make clean -C user
rm -f build/* boot/*.bin boot/initrd rm -f build/* boot/*.bin boot/initrd

View File

@ -2,4 +2,4 @@ ata0-slave: type=cdrom, path=./build/Hazel.iso, status=inserted
magic_break: enabled=1 magic_break: enabled=1
boot: cdrom boot: cdrom
display_library: sdl2 display_library: x

BIN
boot/initrd Normal file → Executable file

Binary file not shown.

114
include/kernel/ps2.h Normal file
View File

@ -0,0 +1,114 @@
#ifndef HAZEL_PS2_H
#define HAZEL_PS2_H
#define PS2_8042_DATA 0x60
#define PS2_8042_STATUS 0x64
#define PS2_8042_COMMAND 0x64
// SCANCODES
#define KBD_ESC 0x01
#define KBD_1 0x02
#define KBD_2 0x03
#define KBD_3 0x04
#define KBD_4 0x05
#define KBD_5 0x06
#define KBD_6 0x07
#define KBD_7 0x08
#define KBD_8 0x09
#define KBD_9 0x0A
#define KBD_0 0x0B
#define KBD_MINUS 0x0C
#define KBD_EQUALS 0x0D
#define KBD_BACKSPACE 0x0E
#define KBD_TAB 0x0F
#define KBD_Q 0x10
#define KBD_W 0x11
#define KBD_E 0x12
#define KBD_R 0x13
#define KBD_T 0x14
#define KBD_Y 0x15
#define KBD_U 0x16
#define KBD_I 0x17
#define KBD_O 0x18
#define KBD_P 0x19
#define KBD_LBRACKET 0x1A
#define KBD_RBRACKET 0x1B
#define KBD_ENTER 0x1C
#define KBD_LCTRL 0x1D
#define KBD_A 0x1E
#define KBD_S 0x1F
#define KBD_D 0x20
#define KBD_F 0x21
#define KBD_G 0x22
#define KBD_H 0x23
#define KBD_J 0x24
#define KBD_K 0x25
#define KBD_L 0x26
#define KBD_SEMICOLON 0x27
#define KBD_APOSTROPHE 0x28
#define KBD_GRAVE 0x29
#define KBD_LSHIFT 0x2A
#define KBD_BACKSLASH 0x2B
#define KBD_Z 0x2C
#define KBD_X 0x2D
#define KBD_C 0x2E
#define KBD_V 0x2F
#define KBD_B 0x30
#define KBD_N 0x31
#define KBD_M 0x32
#define KBD_COMMA 0x33
#define KBD_PERIOD 0x34
#define KBD_SLASH 0x35
#define KBD_RSHIFT 0x36
#define KBD_PRINTSCREEN 0x37
#define KBD_LALT 0x38
#define KBD_SPACE 0x39
#define KBD_CAPSLOCK 0x3A
#define KBD_F1 0x3B
#define KBD_F2 0x3C
#define KBD_F3 0x3D
#define KBD_F4 0x3E
#define KBD_F5 0x3F
#define KBD_F6 0x40
#define KBD_F7 0x41
#define KBD_F8 0x42
#define KBD_F9 0x43
#define KBD_F10 0x44
#define KBD_NUMLOCK 0x45
#define KBD_SCROLLLOCK 0x46
#define KBD_HOME 0x47
#define KBD_UP 0x48
#define KBD_PAGEUP 0x49
#define KBD_KP_MINUS 0x4A
#define KBD_LEFT 0x4B
#define KBD_KP_5 0x4C
#define KBD_RIGHT 0x4D
#define KBD_KP_PLUS 0x4E
#define KBD_END 0x4F
#define KBD_DOWN 0x50
#define KBD_PAGEDOWN 0x51
#define KBD_INSERT 0x52
#define KBD_DELETE 0x53
#define KBD_SYSRQ 0x54
#define KBD_F11 0x57
#define KBD_F12 0x58
#define KBD_KP_ENTER 0x9C
#define KBD_RCTRL 0x9D
#define KBD_KP_DIVIDE 0xB5
#define KBD_PRINTSCREEN2 0xB7
#define KBD_RALT 0xB8
#define KBD_HOME2 0xC7
#define KBD_UP2 0xC8
#define KBD_PAGEUP2 0xC9
#define KBD_LEFT2 0xCB
#define KBD_RIGHT2 0xCD
#define KBD_END2 0xCF
#define KBD_DOWN2 0xD0
#define KBD_PAGEDOWN2 0xD1
#define KBD_INSERT2 0xD2
#define KBD_DELETE2 0xD3
void ps2_init();
void ps2_handler();
#endif

View File

@ -9,6 +9,10 @@ typedef struct {
uint32_t cr3; uint32_t cr3;
uint32_t *next; uint32_t *next;
uint32_t eip; uint32_t eip;
// Shove these into a different struct
uint8_t *stdin;
uint32_t stdin_len;
} task_t; } task_t;
int task_init(task_t *task, elf_t *elf); int task_init(task_t *task, elf_t *elf);

View File

@ -86,6 +86,14 @@ halt:
hlt hlt
jmp halt jmp halt
global ps2_isr
ps2_isr:
extern ps2_handler
pushad
call ps2_handler
popad
iret
extern ctx extern ctx
extern task_sort extern task_sort
global pit_isr global pit_isr
@ -123,6 +131,7 @@ jmp_user_mode:
mov edx, [esp+8] ; eip arg mov edx, [esp+8] ; eip arg
push (4*8) | 3 push (4*8) | 3
push eax push eax
sti
pushf pushf
push (3*8) | 3 push (3*8) | 3
push edx push edx
@ -151,6 +160,7 @@ syscall:
call [eax] call [eax]
popad popad
mov edx, after_syscall mov edx, after_syscall
sti
sysexit sysexit
extern exception_handler extern exception_handler
@ -267,11 +277,11 @@ global boot_page_tab
align 0x1000 align 0x1000
boot_page_tab: times 1024 dd 0 boot_page_tab: times 1024 dd 0
extern syscall_read
extern syscall_write
global syscall_table global syscall_table
syscall_table: syscall_table:
dd 0 dd syscall_read
extern syscall_write
dd syscall_write dd syscall_write
section .bss section .bss

View File

@ -7,6 +7,7 @@
#include <kernel/pit.h> #include <kernel/pit.h>
#include <kernel/elf.h> #include <kernel/elf.h>
#include <kernel/task.h> #include <kernel/task.h>
#include <kernel/ps2.h>
#include <stdint.h> #include <stdint.h>
kernel_ctx_t ctx = {0}; kernel_ctx_t ctx = {0};
@ -16,6 +17,7 @@ tss_t tss = {0};
extern uint32_t isr_stub_table[32]; extern uint32_t isr_stub_table[32];
extern void pit_isr(void); extern void pit_isr(void);
extern void ps2_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);
@ -25,8 +27,35 @@ 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];
#define FD_STDIN 0
#define FD_STDOUT 1
void syscall_write(stack_frame_t r) { void syscall_write(stack_frame_t r) {
LOG("SYSCALL %08X\n", r.eax); uint32_t fd = r.edi;
uint8_t *buf = (uint8_t *)r.esi;
if (fd == FD_STDOUT) {
LOG("%s", buf);
}
}
void syscall_read(stack_frame_t r) {
uint32_t fd = r.edi;
uint8_t *buf = (uint8_t *)r.esi;
uint32_t len = r.edx;
if (fd == FD_STDOUT) {
// Not yet
} else if (fd == FD_STDIN) {
asm volatile ("sti" ::);
while (ctx.current_task->stdin[ctx.current_task->stdin_len - 1] != '\n') cpu_relax;
if (ctx.current_task->stdin_len > 0) ctx.current_task->stdin[--ctx.current_task->stdin_len] = 0;
memcpy(buf, ctx.current_task->stdin, len);
for (int i = 0; i < 0x1000; i++) ctx.current_task->stdin[i] = 0;
ctx.current_task->stdin_len = 0;
}
}
void syscall_uptime(stack_frame_t r) {
uint64_t *buf = (uint64_t *)r.esi;
*buf = ctx.ticks;
} }
void exception_handler(int_stack_frame_t r) { void exception_handler(int_stack_frame_t r) {
@ -47,8 +76,9 @@ void idt_init(void) {
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
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), TRAP_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); idt_encode_entry(idt, 0x21, (uint32_t)ps2_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
idt_encode_entry(idt, 0x80, (uint32_t)syscall_isr, GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3), TRAP_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;
@ -56,16 +86,10 @@ void idt_init(void) {
asm volatile ("lidt %0" :: "m"(idtr)); asm volatile ("lidt %0" :: "m"(idtr));
} }
void test(void) {
for (;;) {
LOG("B");
}
}
void kernel(multiboot_info_t *info) { void kernel(multiboot_info_t *info) {
if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules
if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map
if (!CHECK_FLAG(info->flags, 12)) goto halt; // VBE data if (!CHECK_FLAG(info->flags, 12)) goto halt; // VBE data
if (serial_port_init(COM1)) ctx.log_method = LOG_COM1; if (serial_port_init(COM1)) ctx.log_method = LOG_COM1;
LOG("Kernel log being sent to COM1\n"); LOG("Kernel log being sent to COM1\n");
@ -78,6 +102,7 @@ void kernel(multiboot_info_t *info) {
idt_init(); idt_init();
pic_remap(PIC_1_START, PIC_2_START); pic_remap(PIC_1_START, PIC_2_START);
ps2_init();
asm volatile ("sti" ::); asm volatile ("sti" ::);
ctx.ticks = 0; ctx.ticks = 0;
pit_init(); pit_init();
@ -95,6 +120,7 @@ void kernel(multiboot_info_t *info) {
tss.ss0 = GDT_SEGMENT_SELECTOR(GDT_KERNEL_DATA, RING0); tss.ss0 = GDT_SEGMENT_SELECTOR(GDT_KERNEL_DATA, RING0);
uint32_t esp0 = 0; uint32_t esp0 = 0;
asm volatile ("mov %%esp, %0" : "=r" (esp0)); asm volatile ("mov %%esp, %0" : "=r" (esp0));
// Questionable
tss.esp0 = esp0; tss.esp0 = esp0;
tss.cs = GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3); tss.cs = GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3);
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);
@ -156,9 +182,9 @@ void kernel(multiboot_info_t *info) {
); );
// Set the ring0 syscall entry // Set the ring0 syscall entry
asm volatile ( asm volatile (
"movl $0x176, %%ecx \n\t" // MSR address "movl $0x176, %%ecx \n\t"
"movl %0, %%eax \n\t" // Lower 32 bits (eip) "movl %0, %%eax \n\t"
"xor %%edx, %%edx \n\t" // Upper 32 bits (zero for 32-bit value) "xor %%edx, %%edx \n\t"
"wrmsr" "wrmsr"
: :
: "r"(syscall) : "r"(syscall)

View File

@ -26,6 +26,6 @@ void pic_remap(int pic1_start, int pic2_start) {
outb(PIC_2_DATA, 0x01); outb(PIC_2_DATA, 0x01);
// Unmask // Unmask
outb(PIC_1_DATA, 0b11111110); outb(PIC_1_DATA, 0b11111101);
outb(PIC_2_DATA, 0b11111110); outb(PIC_2_DATA, 0b11111101);
} }

394
kernel/ps2.c Normal file
View File

@ -0,0 +1,394 @@
#include <kernel/ps2.h>
#include <kernel/io.h>
#include <kernel/pic.h>
#include <kernel/mem.h>
extern kernel_ctx_t ctx;
char shell_buffer[512] = {0};
int shell_index = 0;
// TODO: Support dual ports
void ps2_init() {
// disable ps/2 ports so nothing gets messed up
outb(PS2_8042_COMMAND, 0xAD);
outb(PS2_8042_COMMAND, 0xA7);
// flush output buffer
inb(PS2_8042_DATA);
// get config byte
outb(PS2_8042_COMMAND, 0x20);
uint8_t config = inb(0x60);
// disable IRQs and translation, also make sure 0 vals are 0
config &= 0b00110100;
// write our config byte back
outb(PS2_8042_COMMAND, 0x60);
while (inb(PS2_8042_STATUS) & 0x2) cpu_relax;
outb(PS2_8042_DATA, config);
// perform self test
outb(PS2_8042_COMMAND, 0xAA);
while (!(inb(PS2_8042_STATUS) & 0x1)) cpu_relax;
uint8_t result = inb(PS2_8042_DATA);
if (result == 0x55) LOG("Passed PS/2 self test\n")
else LOG("Failed!\n")
// perform test
outb(PS2_8042_COMMAND, 0xAB);
while (!(inb(PS2_8042_STATUS) & 0x1)) cpu_relax;
result = inb(PS2_8042_DATA);
if (!result) LOG("Passed PS/2 port 1 test\n")
else LOG("Failed!\n")
// enable ps/2
outb(PS2_8042_COMMAND, 0xAE);
// enable IRQ 1
config = 0b01100101;
outb(PS2_8042_COMMAND, 0x60);
while (inb(PS2_8042_STATUS) & 0x2) cpu_relax;
outb(PS2_8042_DATA, config);
}
void push_stdin(const char c) {
ctx.current_task->stdin[ctx.current_task->stdin_len++] = c;
_putchar(c);
}
void ps2_handler() {
uint8_t scancode = inb(0x60);
if (scancode > 0x80) goto eoi;
switch(scancode) {
case KBD_ESC:
break;
case KBD_1:
push_stdin('1');
break;
case KBD_2:
push_stdin('2');
break;
case KBD_3:
push_stdin('3');
break;
case KBD_4:
push_stdin('4');
break;
case KBD_5:
push_stdin('5');
break;
case KBD_6:
push_stdin('6');
break;
case KBD_7:
push_stdin('7');
break;
case KBD_8:
push_stdin('8');
break;
case KBD_9:
push_stdin('9');
break;
case KBD_0:
push_stdin('0');
break;
case KBD_MINUS:
push_stdin('-');
break;
case KBD_EQUALS:
push_stdin('=');
break;
case KBD_BACKSPACE:
/*
if (shell_index > 0) {
//popchar();
shell_buffer[--shell_index] = 0;
}*/
break;
case KBD_TAB:
break;
case KBD_Q:
push_stdin('Q');
break;
case KBD_W:
push_stdin('W');
break;
case KBD_E:
push_stdin('E');
break;
case KBD_R:
push_stdin('R');
break;
case KBD_T:
push_stdin('T');
break;
case KBD_Y:
push_stdin('Y');
break;
case KBD_U:
push_stdin('U');
break;
case KBD_I:
push_stdin('I');
break;
case KBD_O:
push_stdin('O');
break;
case KBD_P:
push_stdin('P');
break;
case KBD_LBRACKET:
push_stdin('[');
break;
case KBD_RBRACKET:
push_stdin(']');
break;
case KBD_ENTER:
/*
if (strcmp(shell_buffer, "PINGAS") == 0) {
printf("andew pingas detected");
} else if (strcmp(shell_buffer, "HELLO") == 0) {
printf("hi");
} else if (strcmp(shell_buffer, "READ") == 0) {
uint8_t sector[512] = {0};
ata_read_sector(ATA_PRIMARY, ATA_MASTER, 0, sector);
for (int i = 0; i < 512; i++) {
push_stdin(sector[i]);
}
} else {
printf("unknown command '%s' idiot", shell_buffer);
}
for (int i = 0; i < 512; i++) {
shell_buffer[i] = 0;
}
shell_index = 0;
*/
push_stdin('\n');
break;
case KBD_LCTRL:
// Handle left control key
break;
case KBD_A:
push_stdin('A');
break;
case KBD_S:
push_stdin('S');
break;
case KBD_D:
push_stdin('D');
break;
case KBD_F:
push_stdin('F');
break;
case KBD_G:
push_stdin('G');
break;
case KBD_H:
push_stdin('H');
break;
case KBD_J:
push_stdin('J');
break;
case KBD_K:
push_stdin('K');
break;
case KBD_L:
push_stdin('L');
break;
case KBD_SEMICOLON:
push_stdin(';');
break;
case KBD_APOSTROPHE:
push_stdin('\'');
break;
case KBD_GRAVE:
push_stdin('`');
break;
case KBD_LSHIFT:
// Handle left shift key
break;
case KBD_BACKSLASH:
push_stdin('\\');
break;
case KBD_Z:
push_stdin('Z');
break;
case KBD_X:
push_stdin('X');
break;
case KBD_C:
push_stdin('C');
break;
case KBD_V:
push_stdin('V');
break;
case KBD_B:
push_stdin('B');
break;
case KBD_N:
push_stdin('N');
break;
case KBD_M:
push_stdin('M');
break;
case KBD_COMMA:
push_stdin(',');
break;
case KBD_PERIOD:
push_stdin('.');
break;
case KBD_SLASH:
push_stdin('/');
break;
case KBD_RSHIFT:
// Handle right shift key
break;
case KBD_PRINTSCREEN:
// Handle print screen key
break;
case KBD_LALT:
// Handle left alt key
break;
case KBD_SPACE:
push_stdin(' ');
break;
case KBD_CAPSLOCK:
// Handle caps lock key
break;
case KBD_F1:
// Handle F1 key
break;
case KBD_F2:
// Handle F2 key
break;
case KBD_F3:
// Handle F3 key
break;
case KBD_F4:
// Handle F4 key
break;
case KBD_F5:
// Handle F5 key
break;
case KBD_F6:
// Handle F6 key
break;
case KBD_F7:
// Handle F7 key
break;
case KBD_F8:
// Handle F8 key
break;
case KBD_F9:
// Handle F9 key
break;
case KBD_F10:
// Handle F10 key
break;
case KBD_NUMLOCK:
// Handle num lock key
break;
case KBD_SCROLLLOCK:
// Handle scroll lock key
break;
case KBD_HOME:
// Handle home key
break;
case KBD_UP:
// Handle up arrow key
break;
case KBD_PAGEUP:
// Handle page up key
break;
case KBD_KP_MINUS:
// Handle keypad minus key
break;
case KBD_LEFT:
// Handle left arrow key
break;
case KBD_KP_5:
// Handle keypad 5 key
break;
case KBD_RIGHT:
// Handle right arrow key
break;
case KBD_KP_PLUS:
// Handle keypad plus key
break;
case KBD_END:
// Handle end key
break;
case KBD_DOWN:
// Handle down arrow key
break;
case KBD_PAGEDOWN:
// Handle page down key
break;
case KBD_INSERT:
// Handle insert key
break;
case KBD_DELETE:
// Handle delete key
break;
case KBD_SYSRQ:
// Handle system request key
break;
case KBD_F11:
// Handle F11 key
break;
case KBD_F12:
// Handle F12 key
break;
case KBD_KP_ENTER:
break;
case KBD_RCTRL:
// Handle right control key
break;
case KBD_KP_DIVIDE:
// Handle keypad divide key
break;
case KBD_PRINTSCREEN2:
// Handle print screen key (alternate)
break;
case KBD_RALT:
// Handle right alt key
break;
case KBD_HOME2:
// Handle home key (alternate)
break;
case KBD_UP2:
// Handle up arrow key (alternate)
break;
case KBD_PAGEUP2:
// Handle page up key (alternate)
break;
case KBD_LEFT2:
// Handle left arrow key (alternate)
break;
case KBD_RIGHT2:
// Handle right arrow key (alternate)
break;
case KBD_END2:
// Handle end key (alternate)
break;
case KBD_DOWN2:
// Handle down arrow key (alternate)
break;
case KBD_PAGEDOWN2:
// Handle page down key (alternate)
break;
case KBD_INSERT2:
// Handle insert key (alternate)
break;
case KBD_DELETE2:
// Handle delete key (alternate)
break;
default:
// Handle unknown scan codes
LOG("Unknown scan code\n");
break;
}
eoi:
pic_send_eoi(1);
}

View File

@ -1,15 +1,39 @@
#include "kernel/kernel.h"
#include <kernel/task.h> #include <kernel/task.h>
#include <kernel/mem.h> #include <kernel/mem.h>
extern uint32_t boot_page_tab[1024]; extern uint32_t boot_page_tab[1024];
extern kernel_ctx_t ctx; extern kernel_ctx_t ctx;
//int task_init(task_t *task, uint32_t *img) {
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");
if (!text) return 0; if (!elf) return 0;
task->eip = elf->e_entry + text->sh_offset; uint8_t *s = (uint8_t *)mmap_find_first_free_block();
/*
memset(s, 0, 0x1000);
int idx = 0;
// Loop section header to find ALLOC sections then allocate them
for (int i = 0; i < elf->e_shnum; i++) {
section_t *sec = (section_t *)((uint32_t)elf + elf->e_shoff + i*elf->e_shentsize);
if (!(sec->sh_flags & 0x2)) continue;
if (!sec->sh_addr) continue;
idx += sec->sh_offset;
memcpy(s + idx, (void *)((uint32_t)elf + sec->sh_offset), sec->sh_offset);
LOG("%d\n", sec->sh_offset);
}
*/
memcpy(s, elf, 0x1000);
//section_t *text = elf_find_section(elf, ".text");
//if (!text) return 0;
task->eip = elf->e_entry;
// 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;
// Allocate a page for stdin
// LATER: Allow for allocating more on demand
task->stdin = (uint8_t *)mmap_find_first_free_block();
task->stdin_len = 0;
uint32_t *page_dir = mmap_find_first_free_block(); uint32_t *page_dir = mmap_find_first_free_block();
task->cr3 = (uint32_t)page_dir - KERNEL_VMA; task->cr3 = (uint32_t)page_dir - KERNEL_VMA;
@ -24,11 +48,16 @@ int task_init(task_t *task, elf_t *elf) {
} }
// Map the ELF image to its specified entry // Map the ELF image to its specified entry
// This will cause problems if the ELF image is larger than 4 MiB so I need to fix this // This will cause problems if the ELF image is larger than 4 MiB so I need to fix this
//page_dir[PAGE_DIR_INDEX(elf->e_entry)] = ((uint32_t)page_tab - KERNEL_VMA) | 7;
page_dir[PAGE_DIR_INDEX(elf->e_entry)] = ((uint32_t)page_tab - KERNEL_VMA) | 7; page_dir[PAGE_DIR_INDEX(elf->e_entry)] = ((uint32_t)page_tab - KERNEL_VMA) | 7;
uint32_t elf_phys = (uint32_t)elf - KERNEL_VMA;
/*
uint32_t elf_phys = (uint32_t)s - KERNEL_VMA;
for (int i = 0; i < 1024; i++) { for (int i = 0; i < 1024; i++) {
page_tab[i] = (elf_phys + 0x1000*i) | 7; page_tab[i] = (elf_phys + 0x1000*i) | 7;
} }
*/
page_tab[PAGE_TAB_INDEX(elf->e_entry)] = ((uint32_t)s - KERNEL_VMA) | 7;
return 1; return 1;
} }

View File

@ -1,2 +1,2 @@
break pit_isr break *(0x08048060)

34
user/Makefile Normal file
View File

@ -0,0 +1,34 @@
CC = i686-elf-gcc
ASM = nasm
# Flags
CFLAGS = -ffreestanding -nostdlib -Wall -Wextra
ASMFLAGS = -f elf32
# Source files
C_SOURCES = $(wildcard *.c)
ASM_SOURCES = $(wildcard *.asm)
# Object files
C_OBJECTS = $(C_SOURCES:.c=.o)
ASM_OBJECTS = $(ASM_SOURCES:.asm=.o)
OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)
# Output binary
OUTPUT = ../boot/initrd
.PHONY: all clean
all: $(OUTPUT)
$(OUTPUT): $(OBJECTS)
$(CC) -ffreestanding -nostdlib $(OBJECTS) -o $(OUTPUT)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.asm
$(ASM) $(ASMFLAGS) -o $@ $<
clean:
rm -f $(OBJECTS) $(OUTPUT)

39
user/shell.c Normal file
View File

@ -0,0 +1,39 @@
#include "../lib/strcmp.h"
void puts(const char *str) {
asm volatile (
"movl $1, %%eax\n\t"
"movl $1, %%edi\n\t"
"movl %0, %%esi\n\t"
"int $0x80"
:
: "r"(str)
: "%eax", "%edi", "%esi"
);
}
void read(int fd, void *buf, int size) {
asm volatile (
"movl $0, %%eax\n\t"
"int $0x80"
:
: "D"(fd), "d"(size), "S"(buf)
: "eax"
);
}
extern char *buf;
void _start() {
char buf1[256] = {0};
puts("Welcome to the Hazel user shell!\n");
while (1) {
puts("> ");
read(0, buf1, 256);
if (!strcmp(buf1, "SKIBIDI")) {
puts("dop dop yes yes!\n");
} else {
puts("unknown command!\n");
}
}
}

View File

@ -1,7 +0,0 @@
[bits 32]
global _start
_start:
mov ecx, 0xDEADBEEF
mov eax, 1
int 0x80
jmp $