some sweet commands to finish up kfs2, gonna start the frame allocator now

This commit is contained in:
Jack Halford 2018-02-28 19:28:48 +01:00
parent 52af278a91
commit bcf58de7ac
8 changed files with 95 additions and 47 deletions

@ -1 +1 @@
Subproject commit 4d6ad9cde926f2ad5d47041e3f3a2cda18f8e11e Subproject commit d66e8cb0e5b10c2097a9aef985b4181694db9ce8

View file

@ -86,3 +86,8 @@ GDTR:
.ptr: .ptr:
DW .gdt_bottom - .gdt_top - 1 ; length of the structure minus 1 DW .gdt_bottom - .gdt_top - 1 ; length of the structure minus 1
DD .gdt_top ; pointer to top of gdt DD .gdt_top ; pointer to top of gdt
section .bss
stack_bottom:
resb 4096 * 16
stack_top:

View file

@ -15,7 +15,7 @@ SECTIONS {
kernel_start = . ; kernel_start = . ;
/* ensure that the multiboot header is at the beginning */ /* ensure that the multiboot header is at the beginning */
.multiboot_header : { KEEP(*(.multiboot_header)) } .multiboot : { KEEP(*(.multiboot)) }
.text : { *(.text .text.*) } .text : { *(.text .text.*) }
.rodata : { *(.rodata .rodata.*) } .rodata : { *(.rodata .rodata.*) }
.data : { *(.data.rel.ro.local*) *(.data.rel.ro .data.rel.ro.*) *(.data.*) } .data : { *(.data.rel.ro.local*) *(.data.rel.ro .data.rel.ro.*) *(.data.*) }

View file

@ -1,4 +1,4 @@
section .multiboot_header section .multiboot
header_start: header_start:
dd 0xe85250d6 ; magic number (multiboot 2) dd 0xe85250d6 ; magic number (multiboot 2)
dd 0 ; architecture 0 (protected mode i386) dd 0 ; architecture 0 (protected mode i386)

View file

@ -1,14 +1,33 @@
extern crate core; extern crate core;
extern crate multiboot2;
use cpuio; use cpuio;
use core::char; use core::char;
use context::CONTEXT;
use vga::*;
pub fn dispatch(command: &str) {
match command {
"shutdown" | "halt" => self::shutdown(),
"reboot" => self::reboot(),
"stack" => self::print_stack(),
"multiboot" => self::mb2_info(),
"memory" => self::mb2_memory(),
"sections" => self::mb2_sections(),
_ => {
set_color!(Red);
println!("`{}': Command unknown ", command);
set_color!();
}
}
}
//TODO implement ACPI to have such functionality //TODO implement ACPI to have such functionality
/// Reboot the kernel /// Reboot the kernel
/// ///
/// If reboot failed, will loop on a halt cmd /// If reboot failed, will loop on a halt cmd
/// ///
pub fn reboot() { fn reboot() {
//TODO disable interrupt here something like : asm volatile ("cli"); //TODO disable interrupt here something like : asm volatile ("cli");
// I will now clear the keyboard buffer // I will now clear the keyboard buffer
@ -29,19 +48,21 @@ pub fn reboot() {
/// ///
/// If shutdown failed, will loop on a halt cmd /// If shutdown failed, will loop on a halt cmd
/// ///
pub fn shutdown() -> ! { fn shutdown() -> ! {
cpuio::outb(0xf4, 0x00);//TODO doesn't work :( cpuio::outb(0xf4, 0x00);//TODO doesn't work :(
println!("Reicv shutdown command. System cannot shutdown properly yet, he is now halt\n"); println!("Reicv shutdown command. System cannot shutdown properly yet, he is now halt\n");
cpuio::halt(); cpuio::halt();
} }
pub fn print_hexdump(data: &[u8], offset: usize) { fn hexdump(start: usize, end: usize) {
let mut address = 0; let mut address = 0;
let data = unsafe { core::slice::from_raw_parts_mut(start as *mut u8, end - start) };
while address <= data.len() { while address <= data.len() {
let end = core::cmp::min(address + 16, data.len()); let next_end = core::cmp::min(address + 16, data.len());
print_line(&data[address..end], address + offset); print_line(&data[address..next_end], address + start);
address = address + 16; address = address + 16;
} }
println!("");
} }
fn is_control(c: char) -> bool { fn is_control(c: char) -> bool {
@ -63,13 +84,53 @@ fn print_line(line: &[u8], address: usize) {
print!("|"); print!("|");
} }
/// Print the kernel stack fn print_stack() {
pub fn print_kernel_stack() {
let esp: usize; let esp: usize;
let ebp: usize; let ebp: usize;
unsafe { asm!("" : "={esp}"(esp), "={ebp}"(ebp):::) }; unsafe { asm!("" : "={esp}"(esp), "={ebp}"(ebp):::) };
println!("{:#x} -> {:#x} (size={} bytes)", ebp, esp, ebp - esp); println!("esp = {:#x}", esp);
let slice = unsafe { core::slice::from_raw_parts_mut(ebp as *mut u8, ebp - esp) }; println!("ebp = {:#x}", ebp);
print_hexdump(slice, ebp); println!("size = {:#X} bytes", ebp - esp);
println!(""); hexdump(esp, ebp);
}
fn mb2_memory() {
let boot_info = unsafe { multiboot2::load(CONTEXT.boot_info_addr) };
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.start_address(), area.size());
}
}
fn mb2_sections() {
let boot_info = unsafe { multiboot2::load(CONTEXT.boot_info_addr) };
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!(" {: <10} {:#x}, size: {:#x}, flags: {:#X}",
section.name(), section.start_address(), section.size(), section.flags());
}
}
fn mb2_info() {
let boot_info = unsafe { multiboot2::load(CONTEXT.boot_info_addr) };
let command_line_tag = boot_info.command_line_tag()
.expect("Elf-sections tag required");
let bootloader_tag = boot_info.boot_loader_name_tag()
.expect("Elf-sections tag required");
println!("bootloader: {}", bootloader_tag.name());
if command_line_tag.command_line().len() != 0 {
println!("command line: {}", command_line_tag.command_line());
}
} }

View file

@ -4,12 +4,14 @@ use vga;
pub static mut CONTEXT: Context = Context { pub static mut CONTEXT: Context = Context {
current_term: 0, current_term: 0,
boot_info_addr: 0,
vga1: vga::Writer::new(), vga1: vga::Writer::new(),
vga2: vga::Writer::new(), vga2: vga::Writer::new(),
}; };
pub struct Context { pub struct Context {
pub current_term: u8, pub current_term: u8,
pub boot_info_addr: usize,
pub vga1: vga::Writer, pub vga1: vga::Writer,
pub vga2: vga::Writer, pub vga2: vga::Writer,
} }

View file

@ -24,25 +24,7 @@ use context::CONTEXT;
#[no_mangle] #[no_mangle]
pub extern fn kmain(multiboot_info_addr: usize) -> ! { pub extern fn kmain(multiboot_info_addr: usize) -> ! {
let boot_info = unsafe { multiboot2::load(multiboot_info_addr) }; unsafe { CONTEXT.boot_info_addr = multiboot_info_addr };
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 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);
}
unsafe { CONTEXT.vga1.prompt();CONTEXT.vga1.flush(); } unsafe { CONTEXT.vga1.prompt();CONTEXT.vga1.flush(); }
unsafe { CONTEXT.vga2.prompt(); } unsafe { CONTEXT.vga2.prompt(); }

View file

@ -29,6 +29,15 @@ macro_rules! flush {
() => (unsafe { CONTEXT.current_term().flush() }); () => (unsafe { CONTEXT.current_term().flush() });
} }
macro_rules! set_color {
() => (unsafe { CONTEXT.current_term().color_code =
ColorCode::new(Color::White, Color::Black) });
($fg:ident) => (unsafe { CONTEXT.current_term().color_code =
ColorCode::new(Color::$fg, Color::Black) });
($fg:ident, $bg:ident) => (unsafe { CONTEXT.current_term().color_code =
ColorCode::new(Color::$fg, Color::$bg) });
}
pub fn print(args: fmt::Arguments) { pub fn print(args: fmt::Arguments) {
use core::fmt::Write; use core::fmt::Write;
unsafe { CONTEXT.current_term().write_fmt(args).unwrap() }; unsafe { CONTEXT.current_term().write_fmt(args).unwrap() };
@ -58,10 +67,9 @@ impl Writer {
} }
pub fn prompt(&mut self) { pub fn prompt(&mut self) {
let color_code_save = self.color_code; set_color!(Blue);
self.color_code = ColorCode::new(Color::Blue, Color::Black);
self.write_str("> "); self.write_str("> ");
self.color_code = color_code_save; set_color!();
flush!(); flush!();
} }
@ -77,17 +85,7 @@ impl Writer {
self.write_byte(b'\n'); self.write_byte(b'\n');
{ {
let command: &str = &core::str::from_utf8(&self.command).unwrap()[..self.command_len]; let command: &str = &core::str::from_utf8(&self.command).unwrap()[..self.command_len];
match command { console::dispatch(command);
"shutdown" | "halt" => console::shutdown(),
"reboot" => console::reboot(),
"stack" => console::print_kernel_stack(),
_ => {
let color_code_save = self.color_code;
self.color_code = ColorCode::new(Color::Red, Color::Black);
println!("`{}': Command unknown ", command);
self.color_code = color_code_save;
}
}
} }
self.command_len = 0; self.command_len = 0;
self.prompt(); self.prompt();