Build custom root image with ext2 FS, drop BIOS support
This commit is contained in:
parent
fc4301f132
commit
0f6bad1b2d
@ -1,2 +1,7 @@
|
|||||||
[unstable]
|
[unstable]
|
||||||
|
# enable the unstable artifact-dependencies feature, see
|
||||||
|
# https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dependencies
|
||||||
bindeps = true
|
bindeps = true
|
||||||
|
|
||||||
|
[target.x86-64-unknown-none]
|
||||||
|
rustflags = ["-C", "force-unwind-tables", "-C", "link-args=/home/pterpstra/projects/os-rust/kernel/eh_frame.ld"]
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ initrd_path
|
|||||||
kernel_path
|
kernel_path
|
||||||
out_dir_path
|
out_dir_path
|
||||||
capture.pcapng
|
capture.pcapng
|
||||||
|
root.img
|
||||||
|
1128
Cargo.lock
generated
1128
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
12
Cargo.toml
12
Cargo.toml
@ -5,7 +5,7 @@ edition = "2021"
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
bootloader = { version = "0.11.7" }
|
gpt = "4.0.0-rc.3"
|
||||||
kernel = { path = "../kernel", artifact = "bin", target = "x86_64-unknown-none" }
|
kernel = { path = "../kernel", artifact = "bin", target = "x86_64-unknown-none" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -17,9 +17,9 @@ panic = "abort"
|
|||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
strip = false
|
lto = true
|
||||||
debug = 2
|
|
||||||
|
|
||||||
# [workspace]
|
[profile.release.package.kernel]
|
||||||
# members = ["kernel", "init", "test_proc", "toolchain_test"]
|
strip = true
|
||||||
# exclude = ["x86_64", "rust"]
|
opt-level = "z"
|
||||||
|
codegen-units=1
|
||||||
|
BIN
bootloader-x86_64-uefi.efi
Executable file
BIN
bootloader-x86_64-uefi.efi
Executable file
Binary file not shown.
169
build.rs
169
build.rs
@ -1,54 +1,167 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
env,
|
||||||
|
fs,
|
||||||
os::unix::ffi::OsStrExt,
|
os::unix::ffi::OsStrExt,
|
||||||
path::{Path, PathBuf},
|
path::PathBuf,
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern crate bootloader;
|
use gpt::{mbr::ProtectiveMBR, GptConfig};
|
||||||
|
|
||||||
use bootloader::{BiosBoot, UefiBoot};
|
const ROOT_DISK_SIZE_MB: usize = 256;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed=sysroot");
|
println!("cargo:rerun-if-changed=sysroot");
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
println!("cargo:rerun-if-changed=initrd_file_list");
|
||||||
|
println!("cargo:rerun-if-changed=bootloader-x86_64-uefi.efi");
|
||||||
|
|
||||||
// set by cargo, build scripts should use this directory for output files
|
// set by cargo, build scripts should use this directory for output files
|
||||||
let out_dir = std::env::var_os("OUT_DIR").unwrap();
|
let out_dir = std::env::var_os("OUT_DIR").unwrap();
|
||||||
|
|
||||||
|
std::fs::write("out_dir_path", out_dir.as_os_str().as_bytes()).unwrap();
|
||||||
|
|
||||||
let mut initrd_path = out_dir.clone();
|
let mut initrd_path = out_dir.clone();
|
||||||
initrd_path.push("/initrd.tar");
|
initrd_path.push("/initrd.tar");
|
||||||
Command::new("sh")
|
Command::new("bash")
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg(format!("cd sysroot; tar cvf {:?} *", initrd_path))
|
.arg(format!(
|
||||||
.spawn()
|
"cd sysroot; tar cvf {:?} $(cat ../initrd_file_list)",
|
||||||
.unwrap()
|
initrd_path
|
||||||
.wait()
|
))
|
||||||
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// set by cargo's artifact dependency feature, see
|
let kernel = PathBuf::from(env::var_os("CARGO_BIN_FILE_KERNEL_kernel").unwrap());
|
||||||
// https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dependencies
|
|
||||||
let kernel = PathBuf::from(std::env::var_os("CARGO_BIN_FILE_KERNEL_kernel").unwrap());
|
|
||||||
|
|
||||||
// create an UEFI disk image (optional)
|
let mut disk_path = out_dir.clone();
|
||||||
let mut uefi_path = out_dir.clone();
|
disk_path.push("/root.img");
|
||||||
uefi_path.push("/uefi.img");
|
|
||||||
UefiBoot::new(&kernel)
|
Command::new("dd")
|
||||||
.set_ramdisk(Path::new(&initrd_path))
|
.arg("if=/dev/zero")
|
||||||
.create_disk_image(Path::new(&uefi_path))
|
.arg(format!("of={}", disk_path.to_str().unwrap()))
|
||||||
|
.arg("bs=1M")
|
||||||
|
.arg(format!("count={}", ROOT_DISK_SIZE_MB))
|
||||||
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// create a BIOS disk image (optional)
|
let mut disk = GptConfig::new().writable(true).create(&disk_path).unwrap();
|
||||||
let mut bios_path = out_dir.clone();
|
|
||||||
bios_path.push("/bios.img");
|
ProtectiveMBR::new()
|
||||||
BiosBoot::new(&kernel)
|
.overwrite_lba0(disk.device_mut())
|
||||||
.set_ramdisk(Path::new(&initrd_path))
|
|
||||||
.create_disk_image(Path::new(&bios_path))
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("cargo:rustc-env=UEFI_PATH={}", uefi_path.to_string_lossy());
|
let boot_part_id = disk
|
||||||
println!("cargo:rustc-env=BIOS_PATH={}", bios_path.to_string_lossy());
|
.add_partition("boot", 32 * 1024 * 1024, gpt::partition_types::EFI, 0, None)
|
||||||
|
.unwrap();
|
||||||
|
let root_part_id = disk
|
||||||
|
.add_partition(
|
||||||
|
"root",
|
||||||
|
disk.find_free_sectors()[1].1 * disk.logical_block_size().as_u64(),
|
||||||
|
gpt::partition_types::LINUX_FS,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
std::fs::write("kernel_path", kernel.as_os_str().as_bytes()).unwrap();
|
disk.write_inplace().unwrap();
|
||||||
std::fs::write("initrd_path", initrd_path.as_os_str().as_bytes()).unwrap();
|
|
||||||
std::fs::write("out_dir_path", out_dir.as_bytes()).unwrap();
|
let boot_part = &disk.partitions()[&boot_part_id];
|
||||||
|
let root_part = &disk.partitions()[&root_part_id];
|
||||||
|
|
||||||
|
Command::new("dd")
|
||||||
|
.arg(format!("if={}", disk_path.to_str().unwrap()))
|
||||||
|
.arg("of=tmp_ext2.img")
|
||||||
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
||||||
|
.arg(format!("skip={}", root_part.first_lba))
|
||||||
|
.arg(format!("count={}", root_part.sectors_len().unwrap()))
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Command::new("mkfs.ext2")
|
||||||
|
.arg("-O")
|
||||||
|
.arg("^resize_inode")
|
||||||
|
.arg("-d")
|
||||||
|
.arg("sysroot")
|
||||||
|
.arg("tmp_ext2.img")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Command::new("dd")
|
||||||
|
.arg("if=tmp_ext2.img")
|
||||||
|
.arg(format!("of={}", disk_path.to_str().unwrap()))
|
||||||
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
||||||
|
.arg(format!("seek={}", root_part.first_lba))
|
||||||
|
.arg("conv=notrunc")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
fs::remove_file("tmp_ext2.img").unwrap();
|
||||||
|
|
||||||
|
Command::new("dd")
|
||||||
|
.arg(format!("if={}", disk_path.to_str().unwrap()))
|
||||||
|
.arg("of=tmp_esp.img")
|
||||||
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
||||||
|
.arg(format!("skip={}", boot_part.first_lba))
|
||||||
|
.arg(format!("count={}", boot_part.sectors_len().unwrap()))
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Command::new("mkfs.fat")
|
||||||
|
.arg("-g")
|
||||||
|
.arg("64/32")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("12345678")
|
||||||
|
.arg("-n")
|
||||||
|
.arg("kernel-bd3a")
|
||||||
|
.arg("tmp_esp.img")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Command::new("mmd")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("tmp_esp.img")
|
||||||
|
.arg("efi")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("mmd")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("tmp_esp.img")
|
||||||
|
.arg("efi/boot")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("mcopy")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("tmp_esp.img")
|
||||||
|
.arg("bootloader-x86_64-uefi.efi")
|
||||||
|
.arg("::efi/boot/bootx64.efi")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("mcopy")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("tmp_esp.img")
|
||||||
|
.arg(&kernel)
|
||||||
|
.arg("::kernel-x86_64")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("mcopy")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("tmp_esp.img")
|
||||||
|
.arg(&initrd_path)
|
||||||
|
.arg("::ramdisk")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Command::new("dd")
|
||||||
|
.arg("if=tmp_esp.img")
|
||||||
|
.arg(format!("of={}", disk_path.to_str().unwrap()))
|
||||||
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
||||||
|
.arg(format!("seek={}", boot_part.first_lba))
|
||||||
|
.arg("conv=notrunc")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
fs::remove_file("tmp_esp.img").unwrap();
|
||||||
|
|
||||||
|
println!("cargo:rustc-env=DISK_PATH={}", disk_path.to_string_lossy());
|
||||||
}
|
}
|
||||||
|
11
initrd_file_list
Normal file
11
initrd_file_list
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
bin/init
|
||||||
|
bin/syslog
|
||||||
|
bin/vfs
|
||||||
|
bin/devfs
|
||||||
|
bin/tarfs
|
||||||
|
bin/initrd_driver
|
||||||
|
bin/pci
|
||||||
|
bin/partserv
|
||||||
|
bin/ext2
|
||||||
|
bin/ahci
|
||||||
|
etc/pci_config
|
15
src/main.rs
15
src/main.rs
@ -1,7 +1,5 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
// read env variables that were set in build script
|
let disk_path = env!("DISK_PATH");
|
||||||
let uefi_path = env!("UEFI_PATH");
|
|
||||||
//let bios_path = env!("BIOS_PATH");
|
|
||||||
|
|
||||||
let mut cmd = std::process::Command::new("qemu-system-x86_64");
|
let mut cmd = std::process::Command::new("qemu-system-x86_64");
|
||||||
cmd.arg("-nographic");
|
cmd.arg("-nographic");
|
||||||
@ -16,16 +14,9 @@ fn main() {
|
|||||||
cmd.arg("-device").arg("ahci,id=ahci");
|
cmd.arg("-device").arg("ahci,id=ahci");
|
||||||
//cmd.arg("-device").arg("VGA");
|
//cmd.arg("-device").arg("VGA");
|
||||||
cmd.arg("-blockdev").arg(format!(
|
cmd.arg("-blockdev").arg(format!(
|
||||||
"driver=raw,node-name=boot,file.driver=file,file.filename={uefi_path}"
|
"driver=raw,node-name=disk,file.driver=file,file.filename={disk_path}"
|
||||||
));
|
));
|
||||||
//cmd.arg("-blockdev").arg(format!(
|
cmd.arg("-device").arg("ide-hd,drive=disk,bus=ahci.0");
|
||||||
// "driver=raw,node-name=boot,file.driver=file,file.filename={bios_path}"
|
|
||||||
//));
|
|
||||||
cmd.arg("-device").arg("ide-hd,drive=boot,bus=ahci.0");
|
|
||||||
cmd.arg("-blockdev").arg(format!(
|
|
||||||
"driver=raw,node-name=fs,file.driver=file,file.filename=ext2.img"
|
|
||||||
));
|
|
||||||
cmd.arg("-device").arg("ide-hd,drive=fs,bus=ahci.1");
|
|
||||||
cmd.arg("-device")
|
cmd.arg("-device")
|
||||||
.arg("isa-debug-exit,iobase=0xf4,iosize=0x04");
|
.arg("isa-debug-exit,iobase=0xf4,iosize=0x04");
|
||||||
let mut child = cmd.spawn().unwrap();
|
let mut child = cmd.spawn().unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user