Skip to content

Commit 8f89e84

Browse files
bors[bot]phil-opp
andcommitted
Merge #59
59: Strip debug symbols from kernel r=phil-opp a=phil-opp This PR strips debug symbols from the kernel binary to speed up loading. This reduces the boot image size from 5MB to 270KB for blog_os. (The code already works, I just want to clean it up a bit and improve the naming of the string/path variables before merging.) cc @64 Co-authored-by: Philipp Oppermann <[email protected]>
2 parents f48ec03 + 1dc6af5 commit 8f89e84

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

Changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
- Use a stripped copy of the kernel binary (debug info removed) to reduce load times ([#59](https://github.com/rust-osdev/bootloader/pull/59)).
2+
13
# 0.6.0
24

35
- **Breaking**: Don't set the `#[cfg(not(test))]` attribute for the entry point function in the `entry_point` macro

build.rs

+33-19
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,18 @@ fn main() {
2626
process::exit(1);
2727
}
2828
});
29+
let kernel_file_name = kernel
30+
.file_name()
31+
.expect("KERNEL has no valid file name")
32+
.to_str()
33+
.expect("kernel file name not valid utf8");
2934

3035
// check that the kernel file exists
3136
assert!(
3237
kernel.exists(),
3338
format!("KERNEL does not exist: {}", kernel.display())
3439
);
3540

36-
let kernel_file_name = kernel
37-
.file_name()
38-
.expect("KERNEL has no valid file name")
39-
.to_str()
40-
.expect("kernel file name not valid utf8");
41-
let kernel_file_name_replaced = kernel_file_name.replace('-', "_");
42-
let kernel_out_path = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
43-
let kernel_archive_path = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));
44-
4541
// get access to llvm tools shipped in the llvm-tools-preview rustup component
4642
let llvm_tools = match llvm_tools::LlvmTools::new() {
4743
Ok(tools) => tools,
@@ -74,30 +70,48 @@ fn main() {
7470
Kernel executable at `{}`\n", kernel.display());
7571
}
7672

77-
// wrap the kernel executable as binary in a new ELF file
73+
// strip debug symbols from kernel for faster loading
74+
let stripped_kernel_file_name = format!("kernel_stripped-{}", kernel_file_name);
75+
let stripped_kernel = out_dir.join(&stripped_kernel_file_name);
7876
let objcopy = llvm_tools
7977
.tool(&llvm_tools::exe("llvm-objcopy"))
8078
.expect("llvm-objcopy not found in llvm-tools");
81-
let mut cmd = Command::new(objcopy);
79+
let mut cmd = Command::new(&objcopy);
80+
cmd.arg("--strip-debug");
81+
cmd.arg(&kernel);
82+
cmd.arg(&stripped_kernel);
83+
let exit_status = cmd
84+
.status()
85+
.expect("failed to run objcopy to strip debug symbols");
86+
if !exit_status.success() {
87+
eprintln!("Error: Stripping debug symbols failed");
88+
process::exit(1);
89+
}
90+
91+
// wrap the kernel executable as binary in a new ELF file
92+
let stripped_kernel_file_name_replaced = stripped_kernel_file_name.replace('-', "_");
93+
let kernel_bin = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
94+
let kernel_archive = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));
95+
let mut cmd = Command::new(&objcopy);
8296
cmd.arg("-I").arg("binary");
8397
cmd.arg("-O").arg("elf64-x86-64");
8498
cmd.arg("--binary-architecture=i386:x86-64");
8599
cmd.arg("--rename-section").arg(".data=.kernel");
86100
cmd.arg("--redefine-sym").arg(format!(
87101
"_binary_{}_start=_kernel_start_addr",
88-
kernel_file_name_replaced
102+
stripped_kernel_file_name_replaced
89103
));
90104
cmd.arg("--redefine-sym").arg(format!(
91105
"_binary_{}_end=_kernel_end_addr",
92-
kernel_file_name_replaced
106+
stripped_kernel_file_name_replaced
93107
));
94108
cmd.arg("--redefine-sym").arg(format!(
95109
"_binary_{}_size=_kernel_size",
96-
kernel_file_name_replaced
110+
stripped_kernel_file_name_replaced
97111
));
98-
cmd.current_dir(kernel.parent().expect("KERNEL has no valid parent dir"));
99-
cmd.arg(&kernel_file_name);
100-
cmd.arg(&kernel_out_path);
112+
cmd.current_dir(&out_dir);
113+
cmd.arg(&stripped_kernel_file_name);
114+
cmd.arg(&kernel_bin);
101115
let exit_status = cmd.status().expect("failed to run objcopy");
102116
if !exit_status.success() {
103117
eprintln!("Error: Running objcopy failed");
@@ -115,8 +129,8 @@ fn main() {
115129
});
116130
let mut cmd = Command::new(ar);
117131
cmd.arg("crs");
118-
cmd.arg(&kernel_archive_path);
119-
cmd.arg(&kernel_out_path);
132+
cmd.arg(&kernel_archive);
133+
cmd.arg(&kernel_bin);
120134
let exit_status = cmd.status().expect("failed to run ar");
121135
if !exit_status.success() {
122136
eprintln!("Error: Running ar failed");

0 commit comments

Comments
 (0)