Skip to content
Snippets Groups Projects
Commit d6707183 authored by Eemeli Lehtonen's avatar Eemeli Lehtonen
Browse files

rusty multiboot1 & multiboot2

parent ef189114
No related branches found
No related tags found
No related merge requests found
......@@ -56,6 +56,7 @@ KERNEL_DEPS := ${BOOT_OBJ} ${KERNEL_LIB}
LD_M_x86_64 := elf_x86_64
LD_M_x86 := elf_i386
LD_FLAGS ?=
#LD_FLAGS += --whole-archive
LD_FLAGS += ${KERNEL_DEPS}
LD_FLAGS += -o ${KERNEL_ELF}
LD_FLAGS += --gc-sections
......@@ -82,6 +83,13 @@ QEMU_FLAGS += -kernel ${KERNEL_ELF}
qemu : ${KERNEL_ELF}
${QEMU_${ARCH}} ${QEMU_FLAGS}
.PHONY : build qemu
# objdump
objdump : ${KERNEL_ELF}
objdump -D ${KERNEL_ELF}
readelf : ${KERNEL_ELF}
readelf --all ${KERNEL_ELF}
.PHONY : build qemu objdump readelf
# end
......@@ -3,8 +3,12 @@ ENTRY(start)
SECTIONS {
. = 1M;
.multiboot : ALIGN(4k) {
KEEP(*(.multiboot))
KEEP(*(.multiboot_rust))
}
.boot : ALIGN(4k) {
KEEP(*(.multiboot1))
*(.boot)
}
......
// both cannot coexist (AFAIK.) and QEMU
// cannot boot multiboot2 kernels directly
//
// so multiboot1 it is .. temporarily
// multiboot1 header and glue code
#[cfg(all())]
mod multiboot1;
// multiboot2 header and glue code
#[cfg(any())]
mod multiboot2;
use core::ffi::CStr;
#[allow(unused)]
#[repr(C)]
struct Multiboot1Header {
magic: u32,
flags: u32,
checksum: u32,
_unused: [u32; 5], // header_addr, load_addr, load_end_addr, bss_end_addr, entry_addr
mode_type: u32,
width: u32,
height: u32,
depth: u32,
}
const MAGIC: u32 = 0x1BADB002;
const ALIGN: u32 = 1 << 0;
const MEMINFO: u32 = 1 << 1;
const VIDEO: u32 = 1 << 2;
const FLAGS: u32 = ALIGN | MEMINFO | VIDEO;
#[used]
#[no_mangle]
#[link_section = ".multiboot"]
static MULTIBOOT1_HEADER: Multiboot1Header = Multiboot1Header {
magic: MAGIC,
flags: FLAGS,
checksum: (0x100000000 - (MAGIC + FLAGS) as u64) as u32,
_unused: [0; 5],
mode_type: 0, // 0 = linear graphics
width: 0, // 0 = no preference
height: 0, // 0 = no preference
depth: 0, // 0 = no preference
};
#[derive(Debug, Clone, Copy)]
#[repr(C)]
struct Multiboot1Information {
flags: u32,
optional: [u8; 112],
}
impl Multiboot1Information {
fn bootloader_name(&self) -> Option<&str> {
if (self.flags & 1 << 9) != 0 {
let ptr = u32::from_le_bytes((self.optional[60..=64]).try_into().ok()?) as _;
let s = unsafe { CStr::from_ptr(ptr) };
let s = s.to_str().ok()?;
Some(s)
} else {
None
}
}
fn framebuffer(&self) -> Option<&[u8]> {
if (self.flags & 1 << 12) != 0 {
Some(&self.optional[84..])
} else {
None
}
}
}
#[no_mangle]
extern "C" fn kernel_main(magic_num: u64) {
let mb1_info_pointer = magic_num & u32::MAX as u64;
let mb1_info = unsafe { *(mb1_info_pointer as *const Multiboot1Information) };
crate::println!(
"\0{:?}\n{:#b}\n{:?}",
mb1_info.bootloader_name(),
mb1_info.flags,
mb1_info.framebuffer(),
);
crate::kernel_main();
}
#[allow(unused)]
#[repr(C)]
pub struct Multiboot2Header {
magic: u32,
architecture: u32,
header_length: u32,
checksum: u32,
end_tag_0: u32,
end_tag_1: u32,
}
const MAGIC: u32 = 0xE85250D6;
const ARCH: u32 = 0; // 32 bit (protected mode)
const LEN: u32 = core::mem::size_of::<Multiboot2Header>() as u32;
const CHECKSUM: u32 = (0x100000000 - (MAGIC + ARCH + LEN) as u64) as u32;
#[used]
#[no_mangle]
#[link_section = ".multiboot"]
pub static MULTIBOOT2_HEADER: Multiboot2Header = Multiboot2Header {
magic: MAGIC,
architecture: ARCH,
header_length: LEN,
checksum: CHECKSUM,
end_tag_0: 0,
end_tag_1: 8,
};
#[no_mangle]
pub extern "C" fn kernel_main(_magic_num: u64) {
crate::kernel_main();
}
......@@ -2,38 +2,13 @@
extern kernel_main
;; ----------
;; Multiboot2
;; ----------
section .multiboot2
header_start:
dd 0xE85250D6 ;; multiboot2 magic
dd 0 ;; arch: 32 bit (protected mode)
dd header_end - header_start ;; header length
dd 0x100000000 - (0xE85250D6 + header_end - header_start) ;; checksum
dd 0 ;; end tag
dd 8
header_end:
;; ----------
;; Multiboot1
;; Boot entry
;; ----------
section .multiboot1
dd 0x1BADB002 ;; multiboot1 magic
dd 3 ;; flags
dd 0x100000000 - (0x1BADB002 + 3) ;; checksum
section .boot
global start
bits 32
;; ----------
;; Boot entry
;; ----------
start:
cli
cld
......@@ -43,6 +18,8 @@ start:
;; support checks
call check_multiboot1
push ebx
push ebx
call check_cpuid
call check_long_mode
......@@ -201,7 +178,8 @@ long_mode_start:
; print 'OK'
mov dword [0xb8000], 0x2F4B2F4F
mov rdi, 42
;; take the multiboot info struct pointer
pop rdi
call kernel_main
.halt:
hlt
......
#![no_std]
#![no_main]
#[path = "arch/x86_64/mod.rs"]
pub mod arch;
pub mod vga;
#[panic_handler]
......@@ -8,12 +11,11 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[no_mangle]
#[link_section = ".boot"]
pub extern "C" fn kernel_main(magic_num: u64) -> ! {
fn kernel_main() -> ! {
// null byte clears the VGA buffer
print!("\0");
println!("Hello from Hyperion, magic_num = {magic_num}");
// print!("\0");
// println!("Hello from Hyperion, pointer = {pointer:#x}, fb = {fb:#x}");
loop {
unsafe {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment