The problem
I'm getting the following error message if I run qemu-system-x86_64 -m 4G my_os.iso
:
Expected behaviour
If I have the following code in my main.rs
:
#![no_std]
#![no_main]
use os::println;
use stivale_boot::v2::{StivaleAnyVideoTag, StivaleHeader};
pub const OS_STACK_SIZE: usize = 8_192;
pub static OS_STACK: [u8; OS_STACK_SIZE] = [0; OS_STACK_SIZE];
#[no_mangle]
pub extern "C" fn os_entry() -> ! {
println!("Starting OS...");
loop {}
}
#[used]
#[no_mangle]
#[link_section = ".stivale2hdr"]
pub static STIVALE_HEADER: StivaleHeader = StivaleHeader::new()
.stack(unsafe { OS_STACK.as_ptr().offset(OS_STACK_SIZE as isize) })
.flags(0b11110)
.tags(&ANY_VIDEO_HEADER_TAG as *const StivaleAnyVideoTag as *const ());
pub static ANY_VIDEO_HEADER_TAG: StivaleAnyVideoTag = StivaleAnyVideoTag::new().preference(1);
then it's working and I'm getting:
Reproduction steps
Do cargo new os
first.
You just have to copy+paste the following into the src
directory:
target.json
{
"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",
"pre-link-args": {
"ld.lld": [
"-Tlinker.ld"
]
}
}
linker.ld
OUTPUT_FORMAT(elf64-x86-64)
OUTPUT_ARCH(i386:x86-64)
ENTRY(pornos_entry)
PHDRS {
null PT_NULL FLAGS(0) ; /* Null segment */
text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
}
SECTIONS {
. = 0xffffffff80000000;
.text : {
*(.text .text.*)
} :text
. += CONSTANT(MAXPAGESIZE);
.stivale2hdr : {
KEEP(*(.stivale2hdr))
} :rodata
.rodata : {
*(.rodata .rodata.*)
} :rodata
. += CONSTANT(MAXPAGESIZE);
.data : {
*(.data .data.*)
} :data
.bss : {
*(COMMON)
*(.bss .bss.*)
} :data
}
main.rs
:
#![no_std]
#![no_main]
use stivale_boot::v2::{StivaleAnyVideoTag, StivaleHeader};
#[no_mangle]
pub extern "C" fn os_entry() -> ! {
loop {}
}
lib.rs
:
pub mod stivale;
stivale/mod.rs
(do mkdir -p stivale
before)
use stivale_boot::v2::{StivaleAnyVideoTag, StivaleHeader};
pub const OS_STACK_SIZE: usize = 8_192;
pub static OS_STACK: [u8; OS_STACK_SIZE] = [0; OS_STACK_SIZE];
#[used]
#[no_mangle]
#[link_section = ".stivale2hdr"]
pub static STIVALE_HEADER: StivaleHeader = StivaleHeader::new()
.stack(unsafe { OS_STACK.as_ptr().offset(OS_STACK_SIZE as isize) })
.flags(0b11110)
.tags(&ANY_VIDEO_HEADER_TAG as *const StivaleAnyVideoTag as *const ());
pub static ANY_VIDEO_HEADER_TAG: StivaleAnyVideoTag = StivaleAnyVideoTag::new().preference(1);
.cargo/config.toml
(do mkdir .cargo
before)
[build]
target = "target.json"
[unstable]
build-std = ["core", "compiler_builtins"]
build-std-features = ["compiler-builtins-mem"]
<limine.cfg>
# Timeout in seconds that Limine will use before automatically booting.
TIMEOUT=5
# The entry name that will be displayed in the boot menu
:CustomOS
# Change the protocol line depending on the used protocol.
PROTOCOL=stivale2
# Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located.
KERNEL_PATH=boot:///os
Also execute the following:
cargo +nightly build -Zbuild-std
cargo +nightly build
git clone https://github.com/limine-bootloader/limine.git --branch=v2.0-branch-binary --depth=1
mkdir isodir
make -C limine
cp -v target/target/debug/os limine.cfg limine/limine.sys limine/limine-cd.bin limine/limine-eltorito-efi.bin isodir/
xorriso -as mkisofs -b limine-cd.bin \
-no-emul-boot -boot-load-size 4 -boot-info-table \
--efi-boot limine-eltorito-efi.bin \
-efi-boot-part --efi-boot-image --protective-msdos-label \
isodir/ -o os.iso
Afterwards, start qemu
with: qemu-system-x86_64 -m 4G os.iso
and select the CustomOS
entry. Afterwards the given error message should appear.