rudimentary hexdump

This commit is contained in:
Jack Halford 2018-02-26 13:15:12 +01:00
parent 0877ac2cc6
commit 063cab66f2
5 changed files with 130 additions and 50 deletions

View file

@ -9,6 +9,7 @@ start:
call check_multiboot call check_multiboot
lgdt [GDTR.ptr] ; load the new gdt lgdt [GDTR.ptr] ; load the new gdt
jmp GDTR.gdt_cs:x86_start jmp GDTR.gdt_cs:x86_start
; jmp x86_start
error: error:
mov dword [0xb8000], 0x4f524f45 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 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ]
DB 0x0 ; Base ( bits 24 -31 ) DB 0x0 ; Base ( bits 24 -31 )
.gdt_ss: equ $ - .gdt_top; the stack segment Aka KERNEL STACK ; .gdt_ss: equ $ - .gdt_top; the stack segment Aka KERNEL STACK
DW 0x0 ; Limit ( bits 0 -15 ) ; DW 0x0 ; Limit ( bits 0 -15 )
DW 0x0 ; Base ( bits 0 -15 ) ; DW 0x0 ; Base ( bits 0 -15 )
DB 0x0 ; Base ( bits 16 -23 ) ; 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 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 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ]
DB 0x0 ; Base ( bits 24 -31 ) ; DB 0x0 ; Base ( bits 24 -31 )
.gdt_es: equ $ - .gdt_top; the extra segment Aka USER CODE ; .gdt_es: equ $ - .gdt_top; the extra segment Aka USER CODE
DW 0xffff ; Limit ( bits 0 -15 ) ; DW 0xffff ; Limit ( bits 0 -15 )
DW 0x0 ; Base ( bits 0 -15 ) ; DW 0x0 ; Base ( bits 0 -15 )
DB 0x0 ; Base ( bits 16 -23 ) ; 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 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 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ]
DB 0x0 ; Base ( bits 24 -31 ) ; DB 0x0 ; Base ( bits 24 -31 )
.gdt_fs: equ $ - .gdt_top; the other segment Aka USER DATA ; .gdt_fs: equ $ - .gdt_top; the other segment Aka USER DATA
DW 0xffff ; Limit ( bits 0 -15 ) ; DW 0xffff ; Limit ( bits 0 -15 )
DW 0x0 ; Base ( bits 0 -15 ) ; DW 0x0 ; Base ( bits 0 -15 )
DB 0x0 ; Base ( bits 16 -23 ) ; 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 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 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ]
DB 0x0 ; Base ( bits 24 -31 ) ; DB 0x0 ; Base ( bits 24 -31 )
.gdt_gs: equ $ - .gdt_top; the other segment Aka USER STACK ; .gdt_gs: equ $ - .gdt_top; the other segment Aka USER STACK
DW 0x0 ; Limit ( bits 0 -15 ) ; DW 0x0 ; Limit ( bits 0 -15 )
DW 0x0 ; Base ( bits 0 -15 ) ; DW 0x0 ; Base ( bits 0 -15 )
DB 0x0 ; Base ( bits 16 -23 ) ; 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 ; [ 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 0x00 ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ]
DB 0x0 ; Base ( bits 24 -31 ) ; DB 0x0 ; Base ( bits 24 -31 )
.gdt_bottom: .gdt_bottom:
.ptr: .ptr:

View file

@ -5,9 +5,10 @@ SECTIONS {
/* GDT for the win */ /* GDT for the win */
. = 0x800; . = 0x800;
.gdt : {KEEP(*(.gdt))} .gdt : {KEEP(*(.gdt))}
/* VGA, cannot use section for this */ /* VGA, cannot use section for this */
VGA_PTR = 0xb8000;
. = 0xb8000; . = 0xb8000;
VGA_PTR = . ;
. += 80 * 25 * 2; . += 80 * 25 * 2;
. = 1M; . = 1M;

View file

@ -1,4 +1,7 @@
extern crate core;
use cpuio; use cpuio;
use core::char;
//TODO implement ACPI to have such functionality //TODO implement ACPI to have such functionality
/// Reboot the kernel /// Reboot the kernel
@ -32,10 +35,85 @@ pub fn shutdown() -> ! {
cpuio::halt(); 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 /// Print the kernel stack
/// ///
pub fn print_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!("");
} }

View file

@ -42,24 +42,26 @@ pub extern fn kmain(multiboot_information_address: usize) -> ! {
// format_args!("{: ^80}", r#" ' ,/ ; | .' "#), // format_args!("{: ^80}", r#" ' ,/ ; | .' "#),
// format_args!("{: ^80}", r#" '--' `---' "#)); // format_args!("{: ^80}", r#" '--' `---' "#));
// unsafe { CONTEXT.current_term().color_code = ColorCode::new(Color::White, Color::Black); } // 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() // let boot_info = unsafe{ multiboot2::load(multiboot_information_address) };
.expect("Memory map tag required"); // let memory_map_tag = boot_info.memory_map_tag()
// .expect("Memory map tag required");
println!("memory areas:"); // println!("memory areas:");
for area in memory_map_tag.memory_areas() { // for area in memory_map_tag.memory_areas() {
println!(" start: 0x{:x}, length: 0x{:x}", // println!(" start: 0x{:x}, length: 0x{:x}",
area.base_addr, area.length); // area.base_addr, area.length);
} // }
let elf_sections_tag = boot_info.elf_sections_tag() // let elf_sections_tag = boot_info.elf_sections_tag()
.expect("Elf-sections tag required"); // .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.vga1.prompt();CONTEXT.vga1.flush(); }
unsafe { CONTEXT.vga2.prompt(); } unsafe { CONTEXT.vga2.prompt(); }

View file

@ -39,8 +39,7 @@ const BUFFER_COLS: usize = 80 * 2;
pub struct Writer { pub struct Writer {
pub buffer_pos: usize, pub buffer_pos: usize,
pub color_code: ColorCode, pub color_code: ColorCode,
buffer: [u8; BUFFER_ROWS * BUFFER_COLS], buffer: [u8; BUFFER_ROWS * BUFFER_COLS], command: [u8; 10],
command: [u8; 10],
command_len: usize, command_len: usize,
} }
@ -154,7 +153,6 @@ impl Writer {
} }
fn scroll(&mut self) { fn scroll(&mut self) {
for row in 1..BUFFER_ROWS { for row in 1..BUFFER_ROWS {
for col in 0..BUFFER_COLS { for col in 0..BUFFER_COLS {
let prev_position = ((row - 1) * BUFFER_COLS) + col; let prev_position = ((row - 1) * BUFFER_COLS) + col;