some sweet commands to finish up kfs2, gonna start the frame allocator now
This commit is contained in:
parent
52af278a91
commit
bcf58de7ac
8 changed files with 95 additions and 47 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 4d6ad9cde926f2ad5d47041e3f3a2cda18f8e11e
|
||||
Subproject commit d66e8cb0e5b10c2097a9aef985b4181694db9ce8
|
||||
|
|
@ -86,3 +86,8 @@ GDTR:
|
|||
.ptr:
|
||||
DW .gdt_bottom - .gdt_top - 1 ; length of the structure minus 1
|
||||
DD .gdt_top ; pointer to top of gdt
|
||||
|
||||
section .bss
|
||||
stack_bottom:
|
||||
resb 4096 * 16
|
||||
stack_top:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ SECTIONS {
|
|||
kernel_start = . ;
|
||||
|
||||
/* ensure that the multiboot header is at the beginning */
|
||||
.multiboot_header : { KEEP(*(.multiboot_header)) }
|
||||
.multiboot : { KEEP(*(.multiboot)) }
|
||||
.text : { *(.text .text.*) }
|
||||
.rodata : { *(.rodata .rodata.*) }
|
||||
.data : { *(.data.rel.ro.local*) *(.data.rel.ro .data.rel.ro.*) *(.data.*) }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
section .multiboot_header
|
||||
section .multiboot
|
||||
header_start:
|
||||
dd 0xe85250d6 ; magic number (multiboot 2)
|
||||
dd 0 ; architecture 0 (protected mode i386)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,33 @@
|
|||
extern crate core;
|
||||
extern crate multiboot2;
|
||||
|
||||
use cpuio;
|
||||
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
|
||||
/// Reboot the kernel
|
||||
///
|
||||
/// If reboot failed, will loop on a halt cmd
|
||||
///
|
||||
pub fn reboot() {
|
||||
fn reboot() {
|
||||
//TODO disable interrupt here something like : asm volatile ("cli");
|
||||
|
||||
// I will now clear the keyboard buffer
|
||||
|
|
@ -29,19 +48,21 @@ pub fn reboot() {
|
|||
///
|
||||
/// If shutdown failed, will loop on a halt cmd
|
||||
///
|
||||
pub fn shutdown() -> ! {
|
||||
fn shutdown() -> ! {
|
||||
cpuio::outb(0xf4, 0x00);//TODO doesn't work :(
|
||||
println!("Reicv shutdown command. System cannot shutdown properly yet, he is now halt\n");
|
||||
cpuio::halt();
|
||||
}
|
||||
|
||||
pub fn print_hexdump(data: &[u8], offset: usize) {
|
||||
fn hexdump(start: usize, end: usize) {
|
||||
let mut address = 0;
|
||||
let data = unsafe { core::slice::from_raw_parts_mut(start as *mut u8, end - start) };
|
||||
while address <= data.len() {
|
||||
let end = core::cmp::min(address + 16, data.len());
|
||||
print_line(&data[address..end], address + offset);
|
||||
let next_end = core::cmp::min(address + 16, data.len());
|
||||
print_line(&data[address..next_end], address + start);
|
||||
address = address + 16;
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
|
||||
fn is_control(c: char) -> bool {
|
||||
|
|
@ -63,13 +84,53 @@ fn print_line(line: &[u8], address: usize) {
|
|||
print!("|");
|
||||
}
|
||||
|
||||
/// Print the kernel stack
|
||||
pub fn print_kernel_stack() {
|
||||
fn print_stack() {
|
||||
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, ebp);
|
||||
println!("");
|
||||
println!("esp = {:#x}", esp);
|
||||
println!("ebp = {:#x}", ebp);
|
||||
println!("size = {:#X} bytes", ebp - esp);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@ use vga;
|
|||
|
||||
pub static mut CONTEXT: Context = Context {
|
||||
current_term: 0,
|
||||
boot_info_addr: 0,
|
||||
vga1: vga::Writer::new(),
|
||||
vga2: vga::Writer::new(),
|
||||
};
|
||||
|
||||
pub struct Context {
|
||||
pub current_term: u8,
|
||||
pub boot_info_addr: usize,
|
||||
pub vga1: vga::Writer,
|
||||
pub vga2: vga::Writer,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,25 +24,7 @@ use context::CONTEXT;
|
|||
|
||||
#[no_mangle]
|
||||
pub extern fn kmain(multiboot_info_addr: usize) -> ! {
|
||||
let boot_info = unsafe { multiboot2::load(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.boot_info_addr = multiboot_info_addr };
|
||||
|
||||
unsafe { CONTEXT.vga1.prompt();CONTEXT.vga1.flush(); }
|
||||
unsafe { CONTEXT.vga2.prompt(); }
|
||||
|
|
|
|||
|
|
@ -29,6 +29,15 @@ macro_rules! 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) {
|
||||
use core::fmt::Write;
|
||||
unsafe { CONTEXT.current_term().write_fmt(args).unwrap() };
|
||||
|
|
@ -58,10 +67,9 @@ impl Writer {
|
|||
}
|
||||
|
||||
pub fn prompt(&mut self) {
|
||||
let color_code_save = self.color_code;
|
||||
self.color_code = ColorCode::new(Color::Blue, Color::Black);
|
||||
set_color!(Blue);
|
||||
self.write_str("> ");
|
||||
self.color_code = color_code_save;
|
||||
set_color!();
|
||||
flush!();
|
||||
}
|
||||
|
||||
|
|
@ -77,17 +85,7 @@ impl Writer {
|
|||
self.write_byte(b'\n');
|
||||
{
|
||||
let command: &str = &core::str::from_utf8(&self.command).unwrap()[..self.command_len];
|
||||
match 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;
|
||||
}
|
||||
}
|
||||
console::dispatch(command);
|
||||
}
|
||||
self.command_len = 0;
|
||||
self.prompt();
|
||||
|
|
|
|||
Loading…
Reference in a new issue