Skip to content

Commit e15954b

Browse files
authored
Merge pull request #302 from jasoncouture/load_ramdisk_feature
Load ramdisk feature
2 parents bf4fcea + baed601 commit e15954b

File tree

23 files changed

+539
-168
lines changed

23 files changed

+539
-168
lines changed

Diff for: Cargo.lock

+14-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ members = [
2323
"tests/test_kernels/higher_half",
2424
"tests/test_kernels/pie",
2525
"tests/test_kernels/lto",
26+
"tests/test_kernels/ramdisk"
2627
]
2728
exclude = ["examples/basic", "examples/test_framework"]
2829

@@ -55,6 +56,7 @@ test_kernel_default_settings = { path = "tests/test_kernels/default_settings", a
5556
test_kernel_higher_half = { path = "tests/test_kernels/higher_half", artifact = "bin", target = "x86_64-unknown-none" }
5657
test_kernel_map_phys_mem = { path = "tests/test_kernels/map_phys_mem", artifact = "bin", target = "x86_64-unknown-none" }
5758
test_kernel_pie = { path = "tests/test_kernels/pie", artifact = "bin", target = "x86_64-unknown-none" }
59+
test_kernel_ramdisk = { path = "tests/test_kernels/ramdisk", artifact = "bin", target = "x86_64-unknown-none" }
5860

5961
[profile.dev]
6062
panic = "abort"

Diff for: api/build.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ fn main() {
2222
(88, 9),
2323
(97, 9),
2424
(106, 9),
25-
(115, 1),
26-
(116, 1),
27-
(117, 1),
25+
(115, 9),
26+
(124, 1),
27+
(125, 1),
28+
(126, 1),
2829
];
2930

3031
let mut code = String::new();

Diff for: api/src/config.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ impl BootloaderConfig {
4949
0x3D,
5050
];
5151
#[doc(hidden)]
52-
pub const SERIALIZED_LEN: usize = 118;
52+
pub const SERIALIZED_LEN: usize = 127;
5353

5454
/// Creates a new default configuration with the following values:
5555
///
@@ -97,6 +97,7 @@ impl BootloaderConfig {
9797
aslr,
9898
dynamic_range_start,
9999
dynamic_range_end,
100+
ramdisk_memory,
100101
} = mappings;
101102
let FrameBuffer {
102103
minimum_framebuffer_height,
@@ -145,28 +146,30 @@ impl BootloaderConfig {
145146
},
146147
);
147148

148-
let buf = concat_97_9(
149+
let buf = concat_97_9(buf, ramdisk_memory.serialize());
150+
151+
let buf = concat_106_9(
149152
buf,
150153
match minimum_framebuffer_height {
151154
Option::None => [0; 9],
152155
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
153156
},
154157
);
155158

156-
let buf = concat_106_9(
159+
let buf = concat_115_9(
157160
buf,
158161
match minimum_framebuffer_width {
159162
Option::None => [0; 9],
160163
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
161164
},
162165
);
163166

164-
let log_level = concat_115_1(buf, (*log_level as u8).to_le_bytes());
167+
let log_level = concat_124_1(buf, (*log_level as u8).to_le_bytes());
165168

166169
let frame_buffer_logger_status =
167-
concat_116_1(log_level, (*frame_buffer_logger_status as u8).to_le_bytes());
170+
concat_125_1(log_level, (*frame_buffer_logger_status as u8).to_le_bytes());
168171

169-
concat_117_1(
172+
concat_126_1(
170173
frame_buffer_logger_status,
171174
(*serial_logger_status as u8).to_le_bytes(),
172175
)
@@ -227,6 +230,7 @@ impl BootloaderConfig {
227230
let (&dynamic_range_start, s) = split_array_ref(s);
228231
let (&dynamic_range_end_some, s) = split_array_ref(s);
229232
let (&dynamic_range_end, s) = split_array_ref(s);
233+
let (&ramdisk_memory, s) = split_array_ref(s);
230234

231235
let mappings = Mappings {
232236
kernel_stack: Mapping::deserialize(&kernel_stack)?,
@@ -257,6 +261,7 @@ impl BootloaderConfig {
257261
[1] => Option::Some(u64::from_le_bytes(dynamic_range_end)),
258262
_ => return Err("invalid dynamic range end value"),
259263
},
264+
ramdisk_memory: Mapping::deserialize(&ramdisk_memory)?,
260265
};
261266
(mappings, s)
262267
};
@@ -439,6 +444,9 @@ pub struct Mappings {
439444
///
440445
/// Defaults to `0xffff_ffff_ffff_f000`.
441446
pub dynamic_range_end: Option<u64>,
447+
/// Virtual address to map ramdisk image, if present on disk
448+
/// Defaults to dynamic
449+
pub ramdisk_memory: Mapping,
442450
}
443451

444452
impl Mappings {
@@ -455,6 +463,7 @@ impl Mappings {
455463
aslr: false,
456464
dynamic_range_start: None,
457465
dynamic_range_end: None,
466+
ramdisk_memory: Mapping::new_default(),
458467
}
459468
}
460469

@@ -487,6 +496,7 @@ impl Mappings {
487496
} else {
488497
Option::None
489498
},
499+
ramdisk_memory: Mapping::random(),
490500
}
491501
}
492502
}

Diff for: api/src/info.rs

+6
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ pub struct BootInfo {
5252
pub rsdp_addr: Optional<u64>,
5353
/// The thread local storage (TLS) template of the kernel executable, if present.
5454
pub tls_template: Optional<TlsTemplate>,
55+
/// Ramdisk address, if loaded
56+
pub ramdisk_addr: Optional<u64>,
57+
/// Ramdisk image size, set to 0 if addr is None
58+
pub ramdisk_len: u64,
5559
}
5660

5761
impl BootInfo {
@@ -67,6 +71,8 @@ impl BootInfo {
6771
recursive_index: Optional::None,
6872
rsdp_addr: Optional::None,
6973
tls_template: Optional::None,
74+
ramdisk_addr: Optional::None,
75+
ramdisk_len: 0,
7076
}
7177
}
7278
}

Diff for: bios/common/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod racy_cell;
77
pub struct BiosInfo {
88
pub stage_4: Region,
99
pub kernel: Region,
10+
pub ramdisk: Region,
1011
pub framebuffer: BiosFramebufferInfo,
1112
pub memory_map_addr: u32,
1213
pub memory_map_len: u16,

Diff for: bios/stage-2/src/main.rs

+33-6
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
9898
writeln!(screen::Writer, "loading kernel...").unwrap();
9999
let kernel_len = load_file("kernel-x86_64", KERNEL_DST, &mut fs, &mut disk, disk_buffer);
100100
writeln!(screen::Writer, "kernel loaded at {KERNEL_DST:#p}").unwrap();
101+
let kernel_page_size = (((kernel_len - 1) / 4096) + 1) as usize;
102+
let ramdisk_start = KERNEL_DST.wrapping_add(kernel_page_size * 4096);
103+
writeln!(screen::Writer, "Loading ramdisk...").unwrap();
104+
let ramdisk_len = match try_load_file("ramdisk", ramdisk_start, &mut fs, &mut disk, disk_buffer)
105+
{
106+
Some(s) => s,
107+
None => 0u64,
108+
};
109+
110+
if ramdisk_len == 0 {
111+
writeln!(screen::Writer, "No ramdisk found, skipping.").unwrap();
112+
} else {
113+
writeln!(screen::Writer, "Loaded ramdisk at {ramdisk_start:#p}").unwrap();
114+
}
101115

102116
let memory_map = unsafe { memory_map::query_memory_map() }.unwrap();
103117
writeln!(screen::Writer, "{memory_map:x?}").unwrap();
@@ -129,6 +143,10 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
129143
start: KERNEL_DST as u64,
130144
len: kernel_len,
131145
},
146+
ramdisk: Region {
147+
start: ramdisk_start as u64,
148+
len: ramdisk_len,
149+
},
132150
memory_map_addr: memory_map.as_mut_ptr() as u32,
133151
memory_map_len: memory_map.len().try_into().unwrap(),
134152
framebuffer: BiosFramebufferInfo {
@@ -151,17 +169,16 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
151169
}
152170
}
153171

154-
fn load_file(
172+
fn try_load_file(
155173
file_name: &str,
156174
dst: *mut u8,
157175
fs: &mut fat::FileSystem<disk::DiskAccess>,
158176
disk: &mut disk::DiskAccess,
159177
disk_buffer: &mut AlignedArrayBuffer<16384>,
160-
) -> u64 {
178+
) -> Option<u64> {
161179
let disk_buffer_size = disk_buffer.buffer.len();
162-
let file = fs
163-
.find_file_in_root_dir(file_name, disk_buffer)
164-
.expect("file not found");
180+
let file = fs.find_file_in_root_dir(file_name, disk_buffer)?;
181+
165182
let file_size = file.file_size().into();
166183

167184
let mut total_offset = 0;
@@ -195,7 +212,17 @@ fn load_file(
195212
total_offset += usize::try_from(len).unwrap();
196213
}
197214
}
198-
file_size
215+
Some(file_size)
216+
}
217+
218+
fn load_file(
219+
file_name: &str,
220+
dst: *mut u8,
221+
fs: &mut fat::FileSystem<disk::DiskAccess>,
222+
disk: &mut disk::DiskAccess,
223+
disk_buffer: &mut AlignedArrayBuffer<16384>,
224+
) -> u64 {
225+
try_load_file(file_name, dst, fs, disk, disk_buffer).expect("file not found")
199226
}
200227

201228
/// Taken from https://github.com/rust-lang/rust/blob/e100ec5bc7cd768ec17d75448b29c9ab4a39272b/library/core/src/slice/mod.rs#L1673-L1677

Diff for: bios/stage-4/src/main.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,18 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
5656
PhysAddr::new(info.kernel.start)
5757
};
5858
let kernel_size = info.kernel.len;
59-
let mut frame_allocator = {
60-
let kernel_end = PhysFrame::containing_address(kernel_start + kernel_size - 1u64);
61-
let next_free = kernel_end + 1;
62-
LegacyFrameAllocator::new_starting_at(
63-
next_free,
64-
memory_map.iter().copied().map(MemoryRegion),
65-
)
59+
let next_free_frame = match info.ramdisk.len {
60+
0 => PhysFrame::containing_address(kernel_start + kernel_size - 1u64) + 1,
61+
_ => {
62+
PhysFrame::containing_address(PhysAddr::new(
63+
info.ramdisk.start + info.ramdisk.len - 1u64,
64+
)) + 1
65+
}
6666
};
67+
let mut frame_allocator = LegacyFrameAllocator::new_starting_at(
68+
next_free_frame,
69+
memory_map.iter().copied().map(MemoryRegion),
70+
);
6771

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

131140
load_and_switch_to_kernel(kernel, frame_allocator, page_tables, system_info);

0 commit comments

Comments
 (0)