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:
|
.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:
|
||||||
|
|
|
||||||
|
|
@ -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.*) }
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(); }
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue