diff --git a/kernel-rs/src/arch/x86/boot.asm b/kernel-rs/src/arch/x86/boot.asm index 4a7dfad4..1eb8b68b 100644 --- a/kernel-rs/src/arch/x86/boot.asm +++ b/kernel-rs/src/arch/x86/boot.asm @@ -9,6 +9,7 @@ start: call check_multiboot lgdt [GDTR.ptr] ; load the new gdt jmp GDTR.gdt_cs:x86_start + ; jmp x86_start error: mov dword [0xb8000], 0x4f524f45 @@ -49,37 +50,37 @@ GDTR: 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_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_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_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 0x00 ; [ Access Flags: 0x9A=11110110b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand up => 1)|(readable)|(0) ] - DB 0x00 ; [ 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 0x00 ; [ Access Flags: 0x9A=11110110b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand up => 1)|(readable)|(0) ] +; DB 0x00 ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] +; DB 0x0 ; Base ( bits 24 -31 ) .gdt_bottom: .ptr: diff --git a/kernel-rs/src/arch/x86/linker.ld b/kernel-rs/src/arch/x86/linker.ld index 2c96fb77..91b1860b 100644 --- a/kernel-rs/src/arch/x86/linker.ld +++ b/kernel-rs/src/arch/x86/linker.ld @@ -5,9 +5,10 @@ SECTIONS { /* GDT for the win */ . = 0x800; .gdt : {KEEP(*(.gdt))} + /* VGA, cannot use section for this */ + VGA_PTR = 0xb8000; . = 0xb8000; - VGA_PTR = . ; . += 80 * 25 * 2; . = 1M; diff --git a/kernel-rs/src/console.rs b/kernel-rs/src/console.rs index c5f8a075..2bb2b7ff 100644 --- a/kernel-rs/src/console.rs +++ b/kernel-rs/src/console.rs @@ -1,4 +1,7 @@ +extern crate core; + use cpuio; +use core::char; //TODO implement ACPI to have such functionality /// Reboot the kernel @@ -32,10 +35,85 @@ pub fn shutdown() -> ! { cpuio::halt(); } +pub fn print_hexdump(data: &[u8], offset: usize, display: char, bytes: usize) { + let mut address = 0; + while address <= data.len() { + let end = core::cmp::min(address + 16, data.len()); + print_line(&data[address..end], address + offset, display, bytes); + address = address + 16; + } +} + +fn is_control(c: char) -> bool { + !(c >= ' ' && c <= '~') +} + +fn print_line(line: &[u8], address: usize, display: char, bytes: usize) { + // print address + print!("\n{:08x}:", address); + let words = match (line.len() % bytes) == 0 { + true => line.len() / bytes, + false => (line.len() / bytes) + 1, + }; + for b in 0..words { + let word = match bytes { + 1 => line[b] as u16, + _ => match line.len() == bytes*b + 1 { + true => u16::from_be(((line[bytes * b] as u16) << 8) + 0), + false => u16::from_be(((line[bytes * b] as u16) << 8) + (line[bytes * b + 1] as u16)), + }, + }; + match display { + 'b' => print!(" {:03o}", word), + 'c' => match is_control((word as u8) as char) { + true => print!(" "), + false => print!(" {:03}", (word as u8) as char), + }, + 'C' => print!(" {:02x}", word), + 'x' => print!(" {:04x}", word), + 'o' => print!(" {:06o} ", word), + 'd' => print!(" {:05} ", word), + _ => print!(" {:04x}", word), + } + } + + if display != 'c' { + if (line.len() % 16) > 0 { + // align + let words_left = (16 - line.len()) / bytes; + let word_size = match display { + 'b' => 4, + 'c' => 4, + 'C' => 3, + 'x' => 5, + 'o' => 8, + 'd' => 8, + _ => 5, + }; + for _ in 0..word_size * words_left { + print!(" "); + } + } + + print!(" "); + for c in line { + // replace all control chars with dots + match is_control(*c as char) { + true => print!("."), + false => print!("{}", (*c as char)), + } + } + } +} + /// Print the kernel stack /// pub fn print_kernel_stack() { - println!("It's a stack print"); - + let esp: usize; + let ebp: usize; + unsafe { asm!("": "={esp}"(esp), "={ebp}"(ebp):::) }; + println!("{:#x} -> {:#x} (size={} bytes)", ebp, esp, ebp - esp); + let slice = unsafe { core::slice::from_raw_parts_mut(ebp as *mut u8, ebp - esp) }; + print_hexdump(slice, 0, 'x', ebp - esp); + println!(""); } - diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 2e42ab22..3b7ebedf 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -42,24 +42,26 @@ pub extern fn kmain(multiboot_information_address: usize) -> ! { // format_args!("{: ^80}", r#" ' ,/ ; | .' "#), // format_args!("{: ^80}", r#" '--' `---' "#)); // unsafe { CONTEXT.current_term().color_code = ColorCode::new(Color::White, Color::Black); } - let boot_info = unsafe{ multiboot2::load(multiboot_information_address) }; - let memory_map_tag = boot_info.memory_map_tag() - .expect("Memory map tag required"); + + // let boot_info = unsafe{ multiboot2::load(multiboot_information_address) }; + // let memory_map_tag = boot_info.memory_map_tag() + // .expect("Memory map tag required"); - println!("memory areas:"); - for area in memory_map_tag.memory_areas() { - println!(" start: 0x{:x}, length: 0x{:x}", - area.base_addr, area.length); - } + // println!("memory areas:"); + // for area in memory_map_tag.memory_areas() { + // println!(" start: 0x{:x}, length: 0x{:x}", + // area.base_addr, area.length); + // } - let elf_sections_tag = boot_info.elf_sections_tag() - .expect("Elf-sections tag required"); + // let elf_sections_tag = boot_info.elf_sections_tag() + // .expect("Elf-sections tag required"); + + // println!("kernel sections:"); + // for section in elf_sections_tag.sections() { + // println!(" addr: 0x{:x}, size: 0x{:x}, flags: 0x{:x}", + // section.addr, section.size, section.flags); + // } - println!("kernel sections:"); - for section in elf_sections_tag.sections() { - println!(" addr: 0x{:x}, size: 0x{:x}, flags: 0x{:x}", - section.addr, section.size, section.flags); - } unsafe { CONTEXT.vga1.prompt();CONTEXT.vga1.flush(); } unsafe { CONTEXT.vga2.prompt(); } diff --git a/kernel-rs/src/vga/mod.rs b/kernel-rs/src/vga/mod.rs index 5c054a9b..5b04795b 100644 --- a/kernel-rs/src/vga/mod.rs +++ b/kernel-rs/src/vga/mod.rs @@ -39,8 +39,7 @@ const BUFFER_COLS: usize = 80 * 2; pub struct Writer { pub buffer_pos: usize, pub color_code: ColorCode, - buffer: [u8; BUFFER_ROWS * BUFFER_COLS], - command: [u8; 10], + buffer: [u8; BUFFER_ROWS * BUFFER_COLS], command: [u8; 10], command_len: usize, } @@ -154,7 +153,6 @@ impl Writer { } fn scroll(&mut self) { - for row in 1..BUFFER_ROWS { for col in 0..BUFFER_COLS { let prev_position = ((row - 1) * BUFFER_COLS) + col;