Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplified disk builder #313

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,6 @@ jobs:
- name: Run integration tests
run: cargo test

# test feature gates (only on one OS is enough)
- name: Test with only UEFI feature
if: runner.os == 'Linux'
run: cargo test --no-default-features --features uefi
- name: Test with only BIOS feature
if: runner.os == 'Linux'
run: cargo test --no-default-features --features bios

fmt:
name: Check Formatting
runs-on: ubuntu-latest
Expand Down
18 changes: 14 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"tests/test_kernels/higher_half",
"tests/test_kernels/pie",
"tests/test_kernels/lto",
"tests/test_kernels/ramdisk"
]
exclude = ["examples/basic", "examples/test_framework"]

Expand All @@ -37,10 +38,12 @@ bootloader_api = { version = "0.11.0", path = "api" }
bootloader-x86_64-common = { version = "0.11.0", path = "common" }
bootloader-x86_64-bios-common = { version = "0.11.0", path = "bios/common" }


[features]
default = ["bios", "uefi"]
bios = ["dep:mbrman", "bootloader_test_runner/bios"]
uefi = ["dep:gpt", "bootloader_test_runner/uefi"]
default = ["bios", "uefi", "pxe"]
bios = ["mbrman"]
uefi = ["gpt"]
pxe = ["uefi"]

[dependencies]
anyhow = "1.0.32"
Expand All @@ -55,6 +58,7 @@ test_kernel_default_settings = { path = "tests/test_kernels/default_settings", a
test_kernel_higher_half = { path = "tests/test_kernels/higher_half", artifact = "bin", target = "x86_64-unknown-none" }
test_kernel_map_phys_mem = { path = "tests/test_kernels/map_phys_mem", artifact = "bin", target = "x86_64-unknown-none" }
test_kernel_pie = { path = "tests/test_kernels/pie", artifact = "bin", target = "x86_64-unknown-none" }
test_kernel_ramdisk = { path = "tests/test_kernels/ramdisk", artifact = "bin", target = "x86_64-unknown-none" }

[profile.dev]
panic = "abort"
Expand Down
7 changes: 4 additions & 3 deletions api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ fn main() {
(88, 9),
(97, 9),
(106, 9),
(115, 1),
(116, 1),
(117, 1),
(115, 9),
(124, 1),
(125, 1),
(126, 1),
];

let mut code = String::new();
Expand Down
22 changes: 16 additions & 6 deletions api/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl BootloaderConfig {
0x3D,
];
#[doc(hidden)]
pub const SERIALIZED_LEN: usize = 118;
pub const SERIALIZED_LEN: usize = 127;

/// Creates a new default configuration with the following values:
///
Expand Down Expand Up @@ -97,6 +97,7 @@ impl BootloaderConfig {
aslr,
dynamic_range_start,
dynamic_range_end,
ramdisk_memory,
} = mappings;
let FrameBuffer {
minimum_framebuffer_height,
Expand Down Expand Up @@ -145,28 +146,30 @@ impl BootloaderConfig {
},
);

let buf = concat_97_9(
let buf = concat_97_9(buf, ramdisk_memory.serialize());

let buf = concat_106_9(
buf,
match minimum_framebuffer_height {
Option::None => [0; 9],
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
},
);

let buf = concat_106_9(
let buf = concat_115_9(
buf,
match minimum_framebuffer_width {
Option::None => [0; 9],
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
},
);

let log_level = concat_115_1(buf, (*log_level as u8).to_le_bytes());
let log_level = concat_124_1(buf, (*log_level as u8).to_le_bytes());

let frame_buffer_logger_status =
concat_116_1(log_level, (*frame_buffer_logger_status as u8).to_le_bytes());
concat_125_1(log_level, (*frame_buffer_logger_status as u8).to_le_bytes());

concat_117_1(
concat_126_1(
frame_buffer_logger_status,
(*serial_logger_status as u8).to_le_bytes(),
)
Expand Down Expand Up @@ -227,6 +230,7 @@ impl BootloaderConfig {
let (&dynamic_range_start, s) = split_array_ref(s);
let (&dynamic_range_end_some, s) = split_array_ref(s);
let (&dynamic_range_end, s) = split_array_ref(s);
let (&ramdisk_memory, s) = split_array_ref(s);

let mappings = Mappings {
kernel_stack: Mapping::deserialize(&kernel_stack)?,
Expand Down Expand Up @@ -257,6 +261,7 @@ impl BootloaderConfig {
[1] => Option::Some(u64::from_le_bytes(dynamic_range_end)),
_ => return Err("invalid dynamic range end value"),
},
ramdisk_memory: Mapping::deserialize(&ramdisk_memory)?,
};
(mappings, s)
};
Expand Down Expand Up @@ -439,6 +444,9 @@ pub struct Mappings {
///
/// Defaults to `0xffff_ffff_ffff_f000`.
pub dynamic_range_end: Option<u64>,
/// Virtual address to map ramdisk image, if present on disk
/// Defaults to dynamic
pub ramdisk_memory: Mapping,
}

impl Mappings {
Expand All @@ -455,6 +463,7 @@ impl Mappings {
aslr: false,
dynamic_range_start: None,
dynamic_range_end: None,
ramdisk_memory: Mapping::new_default(),
}
}

Expand Down Expand Up @@ -487,6 +496,7 @@ impl Mappings {
} else {
Option::None
},
ramdisk_memory: Mapping::random(),
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions api/src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ pub struct BootInfo {
pub rsdp_addr: Optional<u64>,
/// The thread local storage (TLS) template of the kernel executable, if present.
pub tls_template: Optional<TlsTemplate>,
/// Ramdisk address, if loaded
pub ramdisk_addr: Optional<u64>,
/// Ramdisk image size, set to 0 if addr is None
pub ramdisk_len: u64,
}

impl BootInfo {
Expand All @@ -67,6 +71,8 @@ impl BootInfo {
recursive_index: Optional::None,
rsdp_addr: Optional::None,
tls_template: Optional::None,
ramdisk_addr: Optional::None,
ramdisk_len: 0,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions bios/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod racy_cell;
pub struct BiosInfo {
pub stage_4: Region,
pub kernel: Region,
pub ramdisk: Region,
pub framebuffer: BiosFramebufferInfo,
pub memory_map_addr: u32,
pub memory_map_len: u16,
Expand Down
44 changes: 38 additions & 6 deletions bios/stage-2/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,25 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
writeln!(screen::Writer, "loading kernel...").unwrap();
let kernel_len = load_file("kernel-x86_64", KERNEL_DST, &mut fs, &mut disk, disk_buffer);
writeln!(screen::Writer, "kernel loaded at {KERNEL_DST:#p}").unwrap();
let kernel_page_size = (((kernel_len - 1) / 4096) + 1) as usize;
let ramdisk_start = KERNEL_DST.wrapping_add(kernel_page_size * 4096);
writeln!(screen::Writer, "Loading ramdisk...").unwrap();
let ramdisk_len = match try_load_file(
"ramdisk",
KERNEL_DST.wrapping_add(kernel_page_size * 4096),
&mut fs,
&mut disk,
disk_buffer,
) {
Some(s) => s,
None => 0u64,
};

if ramdisk_len == 0 {
writeln!(screen::Writer, "No ramdisk found, skipping.").unwrap();
} else {
writeln!(screen::Writer, "Loaded ramdisk at {ramdisk_start:#p}").unwrap();
}

let memory_map = unsafe { memory_map::query_memory_map() }.unwrap();
writeln!(screen::Writer, "{memory_map:x?}").unwrap();
Expand Down Expand Up @@ -129,6 +148,10 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
start: KERNEL_DST as u64,
len: kernel_len,
},
ramdisk: Region {
start: ramdisk_start as u64,
len: ramdisk_len,
},
memory_map_addr: memory_map.as_mut_ptr() as u32,
memory_map_len: memory_map.len().try_into().unwrap(),
framebuffer: BiosFramebufferInfo {
Expand All @@ -151,17 +174,16 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
}
}

fn load_file(
fn try_load_file(
file_name: &str,
dst: *mut u8,
fs: &mut fat::FileSystem<disk::DiskAccess>,
disk: &mut disk::DiskAccess,
disk_buffer: &mut AlignedArrayBuffer<16384>,
) -> u64 {
) -> Option<u64> {
let disk_buffer_size = disk_buffer.buffer.len();
let file = fs
.find_file_in_root_dir(file_name, disk_buffer)
.expect("file not found");
let file = fs.find_file_in_root_dir(file_name, disk_buffer)?;

let file_size = file.file_size().into();

let mut total_offset = 0;
Expand Down Expand Up @@ -195,7 +217,17 @@ fn load_file(
total_offset += usize::try_from(len).unwrap();
}
}
file_size
Some(file_size)
}

fn load_file(
file_name: &str,
dst: *mut u8,
fs: &mut fat::FileSystem<disk::DiskAccess>,
disk: &mut disk::DiskAccess,
disk_buffer: &mut AlignedArrayBuffer<16384>,
) -> u64 {
try_load_file(file_name, dst, fs, disk, disk_buffer).expect("file not found")
}

/// Taken from https://github.com/rust-lang/rust/blob/e100ec5bc7cd768ec17d75448b29c9ab4a39272b/library/core/src/slice/mod.rs#L1673-L1677
Expand Down
23 changes: 16 additions & 7 deletions bios/stage-4/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,18 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
PhysAddr::new(info.kernel.start)
};
let kernel_size = info.kernel.len;
let mut frame_allocator = {
let kernel_end = PhysFrame::containing_address(kernel_start + kernel_size - 1u64);
let next_free = kernel_end + 1;
LegacyFrameAllocator::new_starting_at(
next_free,
memory_map.iter().copied().map(MemoryRegion),
)
let next_free_frame = match info.ramdisk.len {
0 => PhysFrame::containing_address(kernel_start + kernel_size - 1u64) + 1,
_ => {
PhysFrame::containing_address(PhysAddr::new(
info.ramdisk.start + info.ramdisk.len - 1u64,
)) + 1
}
};
let mut frame_allocator = LegacyFrameAllocator::new_starting_at(
next_free_frame,
memory_map.iter().copied().map(MemoryRegion),
);

// We identity-mapped all memory, so the offset between physical and virtual addresses is 0
let phys_offset = VirtAddr::new(0);
Expand Down Expand Up @@ -126,6 +130,11 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
info: framebuffer_info,
}),
rsdp_addr: detect_rsdp(),
ramdisk_addr: match info.ramdisk.len {
0 => None,
_ => Some(info.ramdisk.start),
},
ramdisk_len: info.ramdisk.len,
};

load_and_switch_to_kernel(kernel, frame_allocator, page_tables, system_info);
Expand Down
Loading