diff --git a/src/.cargo/config.toml b/src/.cargo/config.toml new file mode 100644 index 00000000..f6a32a21 --- /dev/null +++ b/src/.cargo/config.toml @@ -0,0 +1,8 @@ + +[target.'cfg(target_os = "none")'] +runner = "cargo run --package kxos-boot --" + +[alias] +kbuild = "build --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" +kimage = "run --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem -- --no-run" +krun = "run --target x86_64-custom.json -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" diff --git a/src/Cargo.lock b/src/Cargo.lock index 654b8b1c..7932282a 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2,23 +2,138 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bootloader" +version = "0.10.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d9b14b92a825ecc3b24e4c163a578af473fbba5f190bfaf48092b29b604504" + +[[package]] +name = "bootloader-locator" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaaa9db3339d32c2622f2e5d0731eb82a468d3439797c9d4fe426744fe2bd551" +dependencies = [ + "json", +] + +[[package]] +name = "buddy_system_allocator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4e85e760e105b46ae0bd1236578793c6c147ae7463fe95c8350296b8bfcb830" +dependencies = [ + "spin 0.7.1", +] + +[[package]] +name = "font8x8" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63201c624b8c8883921b1a1accc8916c4fa9dbfb15d122b26e4dde945b86bbf" + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + [[package]] name = "kxos" version = "0.1.0" +dependencies = [ + "bootloader", + "kxos-frame", +] + +[[package]] +name = "kxos-boot" +version = "0.1.0" +dependencies = [ + "bootloader-locator", + "locate-cargo-manifest", +] [[package]] name = "kxos-frame" version = "0.1.0" dependencies = [ "bitflags", + "bootloader", + "buddy_system_allocator", + "font8x8", + "lazy_static", + "spin 0.5.2", + "volatile", + "x86_64", ] [[package]] name = "kxos-std" version = "0.1.0" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "locate-cargo-manifest" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db985b63431fe09e8d71f50aeceffcc31e720cb86be8dad2f38d084c5a328466" +dependencies = [ + "json", +] + +[[package]] +name = "rustversion" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13287b4da9d1207a4f4929ac390916d64eacfe236a487e9a9f5b3be392be5162" + +[[package]] +name = "volatile" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c" + +[[package]] +name = "x86_64" +version = "0.14.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "100555a863c0092238c2e0e814c1096c1e5cf066a309c696a87e907b5f8c5d69" +dependencies = [ + "bit_field", + "bitflags", + "rustversion", + "volatile", +] diff --git a/src/Cargo.toml b/src/Cargo.toml index 3adae596..cb1e2ca7 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -1,7 +1,22 @@ +[package] +name = "kxos" +version = "0.1.0" +edition = "2021" + +[dependencies] +bootloader = {version="0.10.12"} +kxos-frame = {path = "kxos-frame"} + [workspace] members = [ - "kxos", "kxos-frame", "kxos-std", + "kxos-boot", ] + +[profile.dev] +panic = "abort" + +[profile.release] +panic = "abort" \ No newline at end of file diff --git a/src/kxos-boot/Cargo.toml b/src/kxos-boot/Cargo.toml new file mode 100644 index 00000000..3fd45c96 --- /dev/null +++ b/src/kxos-boot/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "kxos-boot" +version = "0.1.0" +edition = "2021" +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bootloader-locator = "0.0.4" # for locating the `bootloader` dependency on disk +locate-cargo-manifest = "0.2.0" # for locating the kernel's `Cargo.toml` diff --git a/src/kxos-boot/src/main.rs b/src/kxos-boot/src/main.rs new file mode 100644 index 00000000..b989f5ac --- /dev/null +++ b/src/kxos-boot/src/main.rs @@ -0,0 +1,80 @@ +use std::{ + path::{Path, PathBuf}, + process::Command, +}; + +const RUN_ARGS: &[&str] = &["--no-reboot", "-s"]; + +fn main() { + let mut args = std::env::args().skip(1); // skip executable name + let kernel_binary_path = { + let path = PathBuf::from(args.next().unwrap()); + path.canonicalize().unwrap() + }; + println!("{:?}", kernel_binary_path); + + let no_boot = if let Some(arg) = args.next() { + match arg.as_str() { + "--no-run" => true, + other => panic!("unexpected argument `{}`", other), + } + } else { + false + }; + + let bios = create_disk_images(&kernel_binary_path); + + if no_boot { + println!("Created disk image at `{}`", bios.display()); + return; + } + + let mut run_cmd = Command::new("qemu-system-x86_64"); + run_cmd + .arg("-drive") + .arg(format!("format=raw,file={}", bios.display())); + run_cmd.args(RUN_ARGS); + + let exit_status = run_cmd.status().unwrap(); + if !exit_status.success() { + std::process::exit(exit_status.code().unwrap_or(1)); + } +} + +pub fn create_disk_images(kernel_binary_path: &Path) -> PathBuf { + let bootloader_manifest_path = bootloader_locator::locate_bootloader("bootloader").unwrap(); + let kernel_manifest_path = locate_cargo_manifest::locate_manifest().unwrap(); + println!("{:?}", kernel_manifest_path); + + let mut build_cmd = Command::new(env!("CARGO")); + build_cmd.current_dir(bootloader_manifest_path.parent().unwrap()); + build_cmd.arg("builder"); + build_cmd + .arg("--kernel-manifest") + .arg(&kernel_manifest_path); + build_cmd.arg("--kernel-binary").arg(&kernel_binary_path); + build_cmd + .arg("--target-dir") + .arg(kernel_manifest_path.parent().unwrap().join("target")); + build_cmd + .arg("--out-dir") + .arg(kernel_binary_path.parent().unwrap()); + build_cmd.arg("--quiet"); + + if !build_cmd.status().unwrap().success() { + panic!("build failed"); + } + + let kernel_binary_name = kernel_binary_path.file_name().unwrap().to_str().unwrap(); + let disk_image = kernel_binary_path + .parent() + .unwrap() + .join(format!("boot-bios-{}.img", kernel_binary_name)); + if !disk_image.exists() { + panic!( + "Disk image does not exist at {} after bootloader build", + disk_image.display() + ); + } + disk_image +} diff --git a/src/kxos-frame/Cargo.toml b/src/kxos-frame/Cargo.toml index aa6b53fc..559397ec 100644 --- a/src/kxos-frame/Cargo.toml +++ b/src/kxos-frame/Cargo.toml @@ -6,4 +6,14 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bitflags = "1.3" \ No newline at end of file +bitflags = "1.3" +x86_64 = "0.14.2" +spin = "0.5.2" +volatile = {version="0.4.5", features = ["unstable"] } +buddy_system_allocator = "0.6" +bootloader = "0.10.12" +font8x8 = { version = "0.2.5", default-features = false, features = ["unicode"]} + +[dependencies.lazy_static] +version = "1.0" +features = ["spin_no_std"] diff --git a/src/kxos-frame/src/allocator/buddy_system_allocator.rs b/src/kxos-frame/src/allocator/buddy_system_allocator.rs new file mode 100644 index 00000000..c96c1d49 --- /dev/null +++ b/src/kxos-frame/src/allocator/buddy_system_allocator.rs @@ -0,0 +1,20 @@ +use crate::config::KERNEL_HEAP_SIZE; +use buddy_system_allocator::LockedHeap; + +#[global_allocator] +static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); + +#[alloc_error_handler] +pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! { + panic!("Heap allocation error, layout = {:?}", layout); +} + +static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE]; + +pub fn init_heap() { + unsafe { + HEAP_ALLOCATOR + .lock() + .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE); + } +} diff --git a/src/kxos-frame/src/allocator/mod.rs b/src/kxos-frame/src/allocator/mod.rs new file mode 100644 index 00000000..3a8fbc2e --- /dev/null +++ b/src/kxos-frame/src/allocator/mod.rs @@ -0,0 +1,5 @@ +mod buddy_system_allocator; + +pub fn init() { + buddy_system_allocator::init_heap(); +} diff --git a/src/kxos-frame/src/config.rs b/src/kxos-frame/src/config.rs new file mode 100644 index 00000000..9d9d7eb8 --- /dev/null +++ b/src/kxos-frame/src/config.rs @@ -0,0 +1,14 @@ +#![allow(unused)] + +pub const USER_STACK_SIZE: usize = 4096 * 2; +pub const KERNEL_STACK_SIZE: usize = 4096 * 2; +pub const KERNEL_HEAP_SIZE: usize = 0x20_0000; + +pub const PAGE_SIZE: usize = 0x1000; +pub const PAGE_SIZE_BITS: usize = 0xc; +pub const MEM_START: usize = 0x8000_0000; + +pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1; +pub const TRAP_CONTEXT_BASE: usize = TRAMPOLINE - PAGE_SIZE; + +pub const KVA_START: usize = (usize::MAX) << PAGE_SIZE_BITS; diff --git a/src/kxos-frame/src/device/framebuffer.rs b/src/kxos-frame/src/device/framebuffer.rs new file mode 100644 index 00000000..8ddc38b6 --- /dev/null +++ b/src/kxos-frame/src/device/framebuffer.rs @@ -0,0 +1,151 @@ +use bootloader::boot_info::PixelFormat; +use core::fmt; +use font8x8::UnicodeFonts; +use spin::Mutex; +use volatile::Volatile; + +pub static WRITER: Mutex> = Mutex::new(None); + +pub fn init(framebuffer: &'static mut bootloader::boot_info::FrameBuffer) { + let mut writer = Writer { + info: framebuffer.info(), + buffer: Volatile::new(framebuffer.buffer_mut()), + x_pos: 0, + y_pos: 0, + }; + writer.clear(); + + // global writer should not be locked here + let mut global_writer = WRITER.try_lock().unwrap(); + assert!(global_writer.is_none(), "Global writer already initialized"); + *global_writer = Some(writer); +} + +pub struct Writer { + buffer: Volatile<&'static mut [u8]>, + info: bootloader::boot_info::FrameBufferInfo, + x_pos: usize, + y_pos: usize, +} + +impl Writer { + fn newline(&mut self) { + self.y_pos += 8; + self.carriage_return(); + } + + fn carriage_return(&mut self) { + self.x_pos = 0; + } + + /// Erases all text on the screen + pub fn clear(&mut self) { + self.x_pos = 0; + self.y_pos = 0; + self.buffer.fill(0); + } + + fn shift_lines_up(&mut self) { + let offset = self.info.stride * self.info.bytes_per_pixel * 8; + self.buffer.copy_within(offset.., 0); + self.y_pos -= 8; + } + + fn width(&self) -> usize { + self.info.horizontal_resolution + } + + fn height(&self) -> usize { + self.info.vertical_resolution + } + + fn write_char(&mut self, c: char) { + match c { + '\n' => self.newline(), + '\r' => self.carriage_return(), + c => { + if self.x_pos >= self.width() { + self.newline(); + } + while self.y_pos >= (self.height() - 8) { + self.shift_lines_up(); + } + let rendered = font8x8::BASIC_FONTS + .get(c) + .expect("character not found in basic font"); + self.write_rendered_char(rendered); + } + } + } + + fn write_rendered_char(&mut self, rendered_char: [u8; 8]) { + for (y, byte) in rendered_char.iter().enumerate() { + for (x, bit) in (0..8).enumerate() { + let on = *byte & (1 << bit) != 0; + self.write_pixel(self.x_pos + x, self.y_pos + y, on); + } + } + self.x_pos += 8; + } + + fn write_pixel(&mut self, x: usize, y: usize, on: bool) { + let pixel_offset = y * self.info.stride + x; + let color = if on { + match self.info.pixel_format { + PixelFormat::RGB => [0x33, 0xff, 0x66, 0], + PixelFormat::BGR => [0x66, 0xff, 0x33, 0], + _other => [0xff, 0xff, 0xff, 0], + } + } else { + [0, 0, 0, 0] + }; + let bytes_per_pixel = self.info.bytes_per_pixel; + let byte_offset = pixel_offset * bytes_per_pixel; + self.buffer + .index_mut(byte_offset..(byte_offset + bytes_per_pixel)) + .copy_from_slice(&color[..bytes_per_pixel]); + } + + /// Writes the given ASCII string to the buffer. + /// + /// Wraps lines at `BUFFER_WIDTH`. Supports the `\n` newline character. Does **not** + /// support strings with non-ASCII characters, since they can't be printed in the VGA text + /// mode. + fn write_string(&mut self, s: &str) { + for char in s.chars() { + self.write_char(char); + } + } +} + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.write_string(s); + Ok(()) + } +} + +/// Like the `print!` macro in the standard library, but prints to the VGA text buffer. +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::device::framebuffer::_print(format_args!($($arg)*))); +} + +/// Like the `println!` macro in the standard library, but prints to the VGA text buffer. +#[macro_export] +macro_rules! println { + () => ($crate::print!("\n")); + ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); +} + +/// Prints the given formatted string to the VGA text buffer +/// through the global `WRITER` instance. +#[doc(hidden)] +pub fn _print(args: fmt::Arguments) { + use core::fmt::Write; + use x86_64::instructions::interrupts; + + interrupts::without_interrupts(|| { + WRITER.lock().as_mut().unwrap().write_fmt(args).unwrap(); + }); +} diff --git a/src/kxos-frame/src/device/irq.rs b/src/kxos-frame/src/device/irq.rs index 060f9e49..071a40eb 100644 --- a/src/kxos-frame/src/device/irq.rs +++ b/src/kxos-frame/src/device/irq.rs @@ -1,7 +1,100 @@ use crate::prelude::*; -/// An interupt request (IRQ) line. -pub struct IrqLine {} +use alloc::collections::{linked_list::CursorMut, LinkedList}; +use lazy_static::lazy_static; +use spin::Mutex; +use x86_64::{ + set_general_handler, + structures::idt::{InterruptDescriptorTable, InterruptStackFrame, InterruptStackFrameValue}, +}; +lazy_static! { + static ref IDT: InterruptDescriptorTable = { + let mut idt = InterruptDescriptorTable::new(); + set_general_handler!(&mut idt, my_general_hander); + idt + }; +} +lazy_static! { + static ref IRQ_LIST: Vec = { + let mut list: Vec = Vec::new(); + for i in 0..256 { + list.push(IrqLine { + irq_num: i as u8, + callback_list: Mutex::new(Vec::new()), + }); + } + list + }; +} + +lazy_static! { + static ref ID_ALLOCATOR: Mutex = Mutex::new(RecycleAllocator::new()); +} + +pub fn init() { + IDT.load(); +} + +fn my_general_hander(stack_frame: InterruptStackFrame, index: u8, error_code: Option) { + let irq_line = IRQ_LIST.get(index as usize).unwrap(); + let callback_functions = irq_line.callback_list.lock(); + for callback_function in callback_functions.iter() { + callback_function.function.call((InterruptInformation { + interrupt_stack_frame: *stack_frame, + error_code, + },)); + } +} + +struct RecycleAllocator { + current: usize, + recycled: Vec, +} + +impl RecycleAllocator { + pub fn new() -> Self { + RecycleAllocator { + current: 0, + recycled: Vec::new(), + } + } + #[allow(unused)] + pub fn alloc(&mut self) -> usize { + if let Some(id) = self.recycled.pop() { + id + } else { + self.current += 1; + self.current - 1 + } + } + #[allow(unused)] + pub fn dealloc(&mut self, id: usize) { + assert!(id < self.current); + assert!( + !self.recycled.iter().any(|i| *i == id), + "id {} has been deallocated!", + id + ); + self.recycled.push(id); + } +} + +struct CallbackElement { + function: Box, + id: usize, +} + +/// An interrupt request (IRQ) line. +pub struct IrqLine { + irq_num: u8, + callback_list: Mutex>, +} + +#[derive(Debug)] +pub struct InterruptInformation { + pub interrupt_stack_frame: InterruptStackFrameValue, + pub error_code: Option, +} impl IrqLine { /// Acquire an interrupt request line. @@ -10,13 +103,13 @@ impl IrqLine { /// /// This function is marked unsafe as manipulating interrupt lines is /// considered a dangerous operation. - pub unsafe fn acquire(irq_num: u32) -> Arc { - todo!() + pub unsafe fn acquire(irq_num: u8) -> Arc<&'static Self> { + Arc::new(IRQ_LIST.get(irq_num as usize).unwrap()) } /// Get the IRQ number. - pub fn num(&self) -> u32 { - todo!() + pub fn num(&self) -> u8 { + self.irq_num } /// Register a callback that will be invoked when the IRQ is active. @@ -27,9 +120,17 @@ impl IrqLine { /// For each IRQ line, multiple callbacks may be registered. pub fn on_active(&self, callback: F) -> IrqCallbackHandle where - F: Fn(&Self), + F: Fn(InterruptInformation) + Sync + Send + 'static, { - todo!() + let allocate_id = ID_ALLOCATOR.lock().alloc(); + self.callback_list.lock().push(CallbackElement { + function: Box::new(callback), + id: allocate_id, + }); + IrqCallbackHandle { + irq_num: self.irq_num, + id: allocate_id, + } } } @@ -37,10 +138,20 @@ impl IrqLine { /// /// When the handle is dropped, the callback will be unregistered automatically. #[must_use] -pub struct IrqCallbackHandle {} +pub struct IrqCallbackHandle { + irq_num: u8, + id: usize, + // cursor: CursorMut<'a, Box> +} impl Drop for IrqCallbackHandle { fn drop(&mut self) { - todo!("unregister the callback") + let mut a = IRQ_LIST + .get(self.irq_num as usize) + .unwrap() + .callback_list + .lock(); + a.retain(|item| if (*item).id == self.id { false } else { true }); + ID_ALLOCATOR.lock().dealloc(self.id); } } diff --git a/src/kxos-frame/src/device/mod.rs b/src/kxos-frame/src/device/mod.rs index 837af58e..9a06e6a8 100644 --- a/src/kxos-frame/src/device/mod.rs +++ b/src/kxos-frame/src/device/mod.rs @@ -1,7 +1,15 @@ //! Device-related APIs. +pub mod framebuffer; mod io_port; mod irq; +use bootloader::BootInfo; + pub use self::io_port::IoPort; -pub use self::irq::{IrqCallbackHandle, IrqLine}; +pub use self::irq::{InterruptInformation, IrqCallbackHandle, IrqLine}; + +pub fn init(boot_info: &'static mut BootInfo) { + framebuffer::init(boot_info.framebuffer.as_mut().unwrap()); + irq::init(); +} diff --git a/src/kxos-frame/src/lib.rs b/src/kxos-frame/src/lib.rs index f29bfefb..0ddca941 100644 --- a/src/kxos-frame/src/lib.rs +++ b/src/kxos-frame/src/lib.rs @@ -3,9 +3,15 @@ #![allow(dead_code)] #![allow(unused_variables)] #![feature(negative_impls)] +#![feature(abi_x86_interrupt)] +#![feature(alloc_error_handler)] +#![feature(fn_traits)] +#![feature(linked_list_cursors)] extern crate alloc; +mod allocator; +pub mod config; pub mod cpu; pub mod device; mod error; @@ -17,3 +23,29 @@ mod util; pub mod vm; pub use self::error::Error; +use alloc::sync::Arc; +use bootloader::BootInfo; +use device::{InterruptInformation, IrqCallbackHandle, IrqLine}; + +static mut STORE: Option = None; + +pub fn init(boot_info: &'static mut BootInfo) { + allocator::init(); + device::init(boot_info); + device::framebuffer::WRITER.lock().as_mut().unwrap().clear(); + // breakpoint + let breakpoint_irq: Arc<&IrqLine>; + unsafe { + breakpoint_irq = IrqLine::acquire(3); + } + let a = breakpoint_irq.on_active(breakpoint_handler); + let b = breakpoint_irq.on_active(breakpoint_handler); + unsafe { + STORE = Some(a); + } + x86_64::instructions::interrupts::int3(); // new +} + +fn breakpoint_handler(interrupt_information: InterruptInformation) { + println!("EXCEPTION: BREAKPOINT\n{:#?}", interrupt_information); +} diff --git a/src/kxos/Cargo.toml b/src/kxos/Cargo.toml deleted file mode 100644 index e6eef4c8..00000000 --- a/src/kxos/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "kxos" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/src/kxos/src/main.rs b/src/kxos/src/main.rs deleted file mode 100644 index e7a11a96..00000000 --- a/src/kxos/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/src/src/main.rs b/src/src/main.rs new file mode 100644 index 00000000..60c1f165 --- /dev/null +++ b/src/src/main.rs @@ -0,0 +1,30 @@ +#![no_std] +#![no_main] +#![feature(custom_test_frameworks)] +#![forbid(unsafe_code)] + +extern crate kxos_frame; + +use bootloader::{entry_point, BootInfo}; +use core::panic::PanicInfo; +use kxos_frame::println; + +entry_point!(kernel_main); + +fn kernel_main(boot_info: &'static mut BootInfo) -> ! { + // turn the screen gray + // if let Some(framebuffer) = boot_info.framebuffer.as_mut() { + // for byte in framebuffer.buffer_mut() { + // *byte = 0x00; + // } + // } + kxos_frame::init(boot_info); + println!("finish init kxos_frame"); + + loop {} +} + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} diff --git a/src/x86_64-custom.json b/src/x86_64-custom.json new file mode 100644 index 00000000..c1c29f9e --- /dev/null +++ b/src/x86_64-custom.json @@ -0,0 +1,15 @@ +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" + } \ No newline at end of file