diff --git a/kernel-rs/Makefile b/kernel-rs/Makefile index 96353929..b4f1aed8 100644 --- a/kernel-rs/Makefile +++ b/kernel-rs/Makefile @@ -30,11 +30,12 @@ asm_object := $(patsubst src/arch/$(arch)/%.asm, build/arch/$(arch)/%.o, $(asm_ KERNEL_RUN := $(QEMU) -curses -cdrom $(iso) MONITOR := sleep 0.5;\ telnet 127.0.0.1 $(PORT);\ - kill \`ps -x | grep gdb | head -n 2 | tail -n 1 | cut -d \ -f 1 \` + kill \`ps -x | grep gdb | head -n 2 | tail -n 1 | cut -d \ -f 1 \`;\ + kill \`ps -x | grep gdb | head -n 2 | tail -n 1 | cut -d \ -f 2 \` GDB := gdb -q\ -ex \"set arch i386:x86-64\"\ -ex \"file build/kernel-x86.bin\"\ - -ex \"target remote localhost:$(PORTG)\"\ + -ex \"target remote localhost:$(PORTG)\" \ -ex \"continue\" all: $(kernel) @@ -42,6 +43,7 @@ all: $(kernel) build/arch/$(arch)/%.o: src/arch/$(arch)/%.asm Makefile @mkdir -p $(shell dirname $@) @$(NASM) $< -o $@ + @echo "Compiling (ASM) $@..." $(kernel): $(rust_os) $(asm_object) $(linker_script) Makefile @$(LD) -o $(kernel) -T $(linker_script) $(asm_object) $(rust_os) diff --git a/kernel-rs/src/arch/x86/boot.asm b/kernel-rs/src/arch/x86/boot.asm index 0dfa76b8..51629f02 100644 --- a/kernel-rs/src/arch/x86/boot.asm +++ b/kernel-rs/src/arch/x86/boot.asm @@ -1,35 +1,95 @@ global start -extern kmain +extern x86_start section .text bits 32 start: - ; print `OK` to screen - ; mov dword [0xb8000], 0x2f4b2f4f - ; mov word [0xb8000], 0x0248 ; H - ; mov word [0xb8002], 0x0265 ; e - ; mov word [0xb8004], 0x026c ; l - ; mov word [0xb8006], 0x026c ; l - ; mov word [0xb8008], 0x026f ; o - ; mov word [0xb800a], 0x022c ; , - ; mov word [0xb800c], 0x0220 ; - ; mov word [0xb800e], 0x0277 ; w - ; mov word [0xb8010], 0x026f ; o - ; mov word [0xb8012], 0x0272 ; r - ; mov word [0xb8014], 0x026c ; l - ; mov word [0xb8016], 0x0264 ; d - ; mov word [0xb8018], 0x0221 ; ! - lgdt [gdt_info] - call kmain - hlt + mov esp, head_stack + mov edi, ebx + + call check_multiboot + lgdt [GDTR.ptr] + jmp GDTR.gdt_cs:x86_start + +error: + mov dword [0xb8000], 0x4f524f45 + mov dword [0xb8004], 0x4f3a4f52 + mov dword [0xb8008], 0x4f204f20 + mov byte [0xb800a], al + cli +HALT: + hlt + jmp HALT + +check_multiboot: + cmp eax, 0x36d76289 + jne .no_multiboot + ret +.no_multiboot: + mov al, "0" + jmp error + +section .gdt +GDTR: +; http://tuttlem.github.io/2014/07/11/a-gdt-primer.html +.gdt_top: + DD 0, 0 +.gdt_cs: equ $ - .gdt_top; the code segment Aka KERNEL CODE + DW 0xffff ; Limit ( bits 0 -15 ) + DW 0x0 ; Base ( bits 0 -15 ) + DB 0x0 ; Base ( bits 16 -23 ) + DB 0x9A ; [ Access Flags: 0x9A=10011010b = (present)|(Privilege Ring 0=00b)|(1)|(code => 1)|(expand down => 0)|(readable)|(0) ] + DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] + DB 0x0 ; Base ( bits 24 -31 ) + +.gdt_ds: equ $ - .gdt_top; the data segment Aka KERNEL DATA + DW 0xffff ; Limit ( bits 0 -15 ) + DW 0x0 ; Base ( bits 0 -15 ) + DB 0x0 ; Base ( bits 16 -23 ) + DB 0x92 ; [ Access Flags: 0x92=10010010b = (present)|(Privilege Ring 0=00b)|(1)|(data => 0)|(expand down => 0)|(readable)|(0) ] + DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] + DB 0x0 ; Base ( bits 24 -31 ) + +.gdt_ss: equ $ - .gdt_top; the stack segment Aka KERNEL STACK + DW 0x0 ; Limit ( bits 0 -15 ) + DW 0x0 ; Base ( bits 0 -15 ) + DB 0x0 ; Base ( bits 16 -23 ) + DB 0x96 ; [ Access Flags: 0x96=10010110b = (present)|(Privilege Ring 0=00b)|(1)|(data => 0)|(expand up => 1)|(readable)|(0) ] + DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] + DB 0x0 ; Base ( bits 24 -31 ) + +.gdt_es: equ $ - .gdt_top; the extra segment Aka USER CODE + DW 0xffff ; Limit ( bits 0 -15 ) + DW 0x0 ; Base ( bits 0 -15 ) + DB 0x0 ; Base ( bits 16 -23 ) + DB 0xFE ; [ Access Flags: 0x9A=11111110b = (present)|(Privilege Ring 3=11b)|(1)|(code => 1)|(expand up => 1)|(readable)|(0) ] + DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] + DB 0x0 ; Base ( bits 24 -31 ) + +.gdt_fs: equ $ - .gdt_top; the other segment Aka USER DATA + DW 0xffff ; Limit ( bits 0 -15 ) + DW 0x0 ; Base ( bits 0 -15 ) + DB 0x0 ; Base ( bits 16 -23 ) + DB 0xF2 ; [ Access Flags: 0x9A=11110010b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand down => 0)|(readable)|(0) ] + DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] + DB 0x0 ; Base ( bits 24 -31 ) + +.gdt_gs: equ $ - .gdt_top; the other segment Aka USER STACK + DW 0x0 ; Limit ( bits 0 -15 ) + DW 0x0 ; Base ( bits 0 -15 ) + DB 0x0 ; Base ( bits 16 -23 ) + DB 0xF2 ; [ Access Flags: 0x9A=11110110b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand up => 1)|(readable)|(0) ] + DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] + DB 0x0 ; Base ( bits 24 -31 ) + +.gdt_bottom: +.ptr: + DW .gdt_bottom - .gdt_top - 1 + DD .gdt_top -; WARNING: Do not insert random label/lines between gdt_xxx label -gdt_start: - ;TODO GDT entries, like null, kernel code, kernel data, user code, user data, TSS... -gdt_info: - dw gdt_info - gdt_start - 1 - dq gdt_start section .bss - resb 64 +align 4 +stack_end: + resb 4096 * 4 head_stack: diff --git a/kernel-rs/src/arch/x86/linker.ld b/kernel-rs/src/arch/x86/linker.ld index 22edafd1..c0555f73 100644 --- a/kernel-rs/src/arch/x86/linker.ld +++ b/kernel-rs/src/arch/x86/linker.ld @@ -2,18 +2,22 @@ ENTRY(start) OUTPUT_FORMAT(elf32-i386) SECTIONS { + /* GDT for the win */ + . = 0x800; + .gdt : {KEEP(*(.gdt))} + /* VGA, cannot use section for this */ + . = 0xb8000; + VGA_PTR = . ; + . += 80 * 25 * 2; + . = 1M; - - .boot : { - /* ensure that the multiboot header is at the beginning */ - KEEP(*(.multiboot_header)) - } - - .text : { - *(.text) - } - - .stack : { - *(.bss) - } + kernel_start = . ; + /* ensure that the multiboot header is at the beginning */ + .boot : {KEEP(*(.multiboot_header))} + .text : {*(.text)} + /* .rodata BLOCK(4K) : ALIGN(4K) {*(.rodata)} */ + /* .data BLOCK(4K) : ALIGN(4K) {*(.data)} */ +/* load stack */ + .bss : {*(.bss)} + kernel_end = . ; } diff --git a/kernel-rs/src/arch/x86/start.asm b/kernel-rs/src/arch/x86/start.asm new file mode 100644 index 00000000..53125fab --- /dev/null +++ b/kernel-rs/src/arch/x86/start.asm @@ -0,0 +1,25 @@ +global x86_start +extern kmain + +section .text +bits 32 +x86_start: +; we should clear register but it does not work +; mov ax, 0 +; mov ss, ax +; mov ds, ax +; mov es, ax +; mov fs, ax +; mov gs, ax + +; PRINT OK +; mov dword [0xb8000], 0x2f4b2f4f +; hlt + + call kmain + +; if main return, loop forever ; that should NEVER append + cli ; clear interrupt +HALT: + hlt + jmp HALT diff --git a/kernel-rs/src/keyboard.rs b/kernel-rs/src/keyboard.rs index 37f58647..eabca0fa 100644 --- a/kernel-rs/src/keyboard.rs +++ b/kernel-rs/src/keyboard.rs @@ -82,9 +82,9 @@ pub fn kbd_callback() { static mut CTRL: bool = false; static mut ALT: bool = false; // let terminal_two: vga::terminal::Terminal = vga::Screen::new(); - let control = unsafe { cpuio::inb(0x64) }; + let control = cpuio::inb(0x64); if (control & 1) == 1 { - let scancode = unsafe { cpuio::inb(0x60) }; + let scancode = cpuio::inb(0x60); let (is_release, scancode) = check_key_state(scancode); //TODO implement logic to translate scancode->ascii unsafe {//TODO remove unsafe diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index dffe3fd0..5ea57084 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -51,9 +51,9 @@ fn reboot() { fn shutdown() -> ! { cpuio::outb(0xf4, 0x00);//TODO doesn't work :( println!("Reicv shutdown command. System cannot shutdown properly yet, he is now halt\n"); - test cpuio::halt(); } + #[no_mangle] pub extern fn kmain() -> ! { // use vga::VgaScreen;