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
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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!("");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
println!("memory areas:");
|
||||
for area in memory_map_tag.memory_areas() {
|
||||
println!(" start: 0x{:x}, length: 0x{:x}",
|
||||
area.base_addr, area.length);
|
||||
}
|
||||
// let boot_info = unsafe{ multiboot2::load(multiboot_information_address) };
|
||||
// let memory_map_tag = boot_info.memory_map_tag()
|
||||
// .expect("Memory map tag required");
|
||||
|
||||
let elf_sections_tag = boot_info.elf_sections_tag()
|
||||
.expect("Elf-sections 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);
|
||||
// }
|
||||
|
||||
// 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(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue