rudimentary hexdump
This commit is contained in:
parent
0877ac2cc6
commit
063cab66f2
5 changed files with 130 additions and 50 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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!("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(); }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue