diff options
Diffstat (limited to 'src/arch/x86/common')
| -rw-r--r-- | src/arch/x86/common/boot/mod.rs | 2 | ||||
| -rw-r--r-- | src/arch/x86/common/boot/multiboot.S | 11 | ||||
| -rw-r--r-- | src/arch/x86/common/boot/multiboot.rs | 79 | ||||
| -rw-r--r-- | src/arch/x86/common/boot/multiboot2.S | 42 | ||||
| -rw-r--r-- | src/arch/x86/common/forall.rs | 5 | ||||
| -rw-r--r-- | src/arch/x86/common/io/mod.rs | 2 | ||||
| -rw-r--r-- | src/arch/x86/common/io/writer.rs | 72 | ||||
| -rw-r--r-- | src/arch/x86/common/mod.rs | 8 |
8 files changed, 221 insertions, 0 deletions
diff --git a/src/arch/x86/common/boot/mod.rs b/src/arch/x86/common/boot/mod.rs new file mode 100644 index 0000000..b6aebe5 --- /dev/null +++ b/src/arch/x86/common/boot/mod.rs @@ -0,0 +1,2 @@ +mod multiboot; +pub use multiboot::*; diff --git a/src/arch/x86/common/boot/multiboot.S b/src/arch/x86/common/boot/multiboot.S new file mode 100644 index 0000000..8773b1f --- /dev/null +++ b/src/arch/x86/common/boot/multiboot.S @@ -0,0 +1,11 @@ +.set ALIGN, 1<<0 +.set MEMINFO, 1<<1 +.set FLAGS, ALIGN | MEMINFO +.set MAGIC, 0x1BADB002 +.set CHECKSUM, -(MAGIC + FLAGS) + +.section .multiboot.header, "aw" +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM diff --git a/src/arch/x86/common/boot/multiboot.rs b/src/arch/x86/common/boot/multiboot.rs new file mode 100644 index 0000000..09789ce --- /dev/null +++ b/src/arch/x86/common/boot/multiboot.rs @@ -0,0 +1,79 @@ +pub const MULTIBOOT2_BOOTLOADER_MAGIC: u32 = 0x36d76289; +pub const MULTIBOOT_TAG_TYPE_END: u32 = 0; +pub const MULTIBOOT_TAG_TYPE_MMAP: u32 = 6; +pub const MULTIBOOT_TAG_TYPE_FB: u32 = 8; + +use crate::{print, println}; + +pub fn parse_fb_multiboot(mut mem: *mut u32) { + let framebuffer_addr: u64 = unsafe { *(mem as *mut u64) }; + let framebuffer_pitch: u32 = unsafe { *mem.wrapping_add(2) }; + let framebuffer_width: u32 = unsafe { *mem.wrapping_add(3) }; + let framebuffer_height: u32 = unsafe { *mem.wrapping_add(4) }; + let framebuffer_bpp: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8) }; + let framebuffer_type: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) }; + let reserved: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) }; + + println!( + "0x{:x} {:x} {:x} {:x}", + framebuffer_addr, framebuffer_pitch, framebuffer_width, framebuffer_height + ); +} + +pub fn parse_mem_multiboot(mut mem: *mut u32, _size: u32) { + let mut curr_size: u32 = 16; + + while curr_size < _size { + let base_addr: u64 = unsafe { *(mem as *mut u64) }; + let length: u64 = unsafe { *(mem.wrapping_add(2) as *mut u64) }; + let _type: u32 = unsafe { *mem.wrapping_add(4) }; + let reserved: u32 = unsafe { *mem.wrapping_add(5) }; + assert_eq!(reserved, 0, "reserved not 0"); + + //println!("{:x} {:x} {:x}", base_addr, length, _type); + + mem = mem.wrapping_add(6); + curr_size += 24; + } +} + +pub fn parse_multiboot(mut multiboot_bootinfo: *mut u32, multiboot_magic: u32) { + assert_eq!( + multiboot_magic, MULTIBOOT2_BOOTLOADER_MAGIC, + "MULTIBOOT2_BOOTLOADER_MAGIC" + ); + + let total_size: u32 = unsafe { *multiboot_bootinfo }; + let mut size = 8; + multiboot_bootinfo = multiboot_bootinfo.wrapping_add(2); + + while size < total_size { + let _type: u32 = unsafe { *multiboot_bootinfo }; + let _size: u32 = unsafe { *(multiboot_bootinfo.wrapping_add(1)) }; + let mem: *mut u32 = multiboot_bootinfo.wrapping_add(4); + let mem2: *mut u32 = multiboot_bootinfo.wrapping_add(2); + + match _type { + MULTIBOOT_TAG_TYPE_FB => { + parse_fb_multiboot(mem2); + } + MULTIBOOT_TAG_TYPE_MMAP => { + parse_mem_multiboot(mem, _size); + } + _ => {} + } + + let inc_size = (_size / 8 + (_size % 8 != 0) as u32) * 8; + size += inc_size; + + println!("{} {} {}", _type, _size, inc_size); + multiboot_bootinfo = multiboot_bootinfo.wrapping_add((inc_size / 4).try_into().unwrap()); + + if _type == MULTIBOOT_TAG_TYPE_END { + assert_eq!(_size, 8, "MULTIBOOT_TAG_TYPE_END"); + break; + } + } + + assert_eq!(total_size, size, "Multiboot"); +} diff --git a/src/arch/x86/common/boot/multiboot2.S b/src/arch/x86/common/boot/multiboot2.S new file mode 100644 index 0000000..d767ca0 --- /dev/null +++ b/src/arch/x86/common/boot/multiboot2.S @@ -0,0 +1,42 @@ +/* multiboot tags */ +.set TAG_END, 0 +.set TAG_FRAMEBUFFER, 5 + +/* multiboot flags */ +.set TAG_REQUIRED, 0 +.set TAG_OPTIONAL, 1 + +/* multiboot2 header constants */ +.set MAGIC, 0xe85250d6 +.set ARCH, 0 +.set HEADER_LENGTH, (header_end - header_start) +.set CHECKSUM, 0x100000000 - (MAGIC + ARCH + HEADER_LENGTH) + +.section .multiboot2.header, "a" +.align 4 +header_start: + /* magic */ + .align 8 + .long MAGIC + .long ARCH + .long HEADER_LENGTH + .long CHECKSUM + +/* + // framebuffer + .align 8 + .word TAG_FRAMEBUFFER + .word TAG_REQUIRED + .long 20 + .long 1024 + .long 768 + .long 32 +*/ + + /* end tag */ + .align 8 + .word TAG_END + .word TAG_REQUIRED + .long 8 + +header_end: diff --git a/src/arch/x86/common/forall.rs b/src/arch/x86/common/forall.rs new file mode 100644 index 0000000..39988e6 --- /dev/null +++ b/src/arch/x86/common/forall.rs @@ -0,0 +1,5 @@ +use crate::{print, println}; + +pub fn forall() { + println!("forall"); +} diff --git a/src/arch/x86/common/io/mod.rs b/src/arch/x86/common/io/mod.rs new file mode 100644 index 0000000..604e84c --- /dev/null +++ b/src/arch/x86/common/io/mod.rs @@ -0,0 +1,2 @@ +mod writer; +pub use writer::*; diff --git a/src/arch/x86/common/io/writer.rs b/src/arch/x86/common/io/writer.rs new file mode 100644 index 0000000..7361693 --- /dev/null +++ b/src/arch/x86/common/io/writer.rs @@ -0,0 +1,72 @@ +use core::fmt; +use core::fmt::Write; +use lazy_static::lazy_static; +use spin::Mutex; + +#[doc(hidden)] +pub fn _print(args: fmt::Arguments) { + WRITER.lock().write_fmt(args).unwrap(); +} + +lazy_static! { + pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer::new()); +} + +#[derive(Default)] +pub struct Writer { + max_y: isize, + max_x: isize, + x: isize, + y: isize, + addr: u32, +} + +impl Writer { + pub fn new() -> Self { + Self { + x: 0, + y: 0, + max_y: 25, + max_x: 80, + addr: 0xb8000, + } + } + + pub fn write(&mut self, c: char, b: u8) { + let off: isize = self.y * self.max_x + self.x; + let vga_buffer = self.addr as *mut u8; + + if c != '\n' { + unsafe { + *vga_buffer.offset(2 * off) = c as u8; + *vga_buffer.offset(2 * off + 1) = b; + } + self.x += 1; + } else { + self.x = 0; + self.y += 1; + } + + if self.x >= self.max_x { + self.x = 0; + self.y += 1; + } + + if self.y >= self.max_y { + self.y = 0; + } + } + + pub fn print(&mut self, s: &str, b: u8) { + for i in s.chars() { + self.write(i, b); + } + } +} + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.print(s, 0xb); + Ok(()) + } +} diff --git a/src/arch/x86/common/mod.rs b/src/arch/x86/common/mod.rs new file mode 100644 index 0000000..d1d4d98 --- /dev/null +++ b/src/arch/x86/common/mod.rs @@ -0,0 +1,8 @@ +mod forall; +pub use forall::*; + +mod io; +pub use io::*; + +mod boot; +pub use boot::*; |
