Skip to content

Commit d2512aa

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 12645da + e536942 commit d2512aa

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
- Make the physical memory offset configurable through a `BOOTLOADER_PHYSICAL_MEMORY_OFFSET` environment variable ([#58](https://github.com/rust-osdev/bootloader/pull/58)).
2+
- Use a stripped copy of the kernel binary (debug info removed) to reduce load times ([#59](https://github.com/rust-osdev/bootloader/pull/59)).
23

34
# 0.6.0
45

build.rs

+33-19
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,18 @@ fn main() {
2828
process::exit(1);
2929
}
3030
});
31+
let kernel_file_name = kernel
32+
.file_name()
33+
.expect("KERNEL has no valid file name")
34+
.to_str()
35+
.expect("kernel file name not valid utf8");
3136

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

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

79-
// wrap the kernel executable as binary in a new ELF file
75+
// strip debug symbols from kernel for faster loading
76+
let stripped_kernel_file_name = format!("kernel_stripped-{}", kernel_file_name);
77+
let stripped_kernel = out_dir.join(&stripped_kernel_file_name);
8078
let objcopy = llvm_tools
8179
.tool(&llvm_tools::exe("llvm-objcopy"))
8280
.expect("llvm-objcopy not found in llvm-tools");
83-
let mut cmd = Command::new(objcopy);
81+
let mut cmd = Command::new(&objcopy);
82+
cmd.arg("--strip-debug");
83+
cmd.arg(&kernel);
84+
cmd.arg(&stripped_kernel);
85+
let exit_status = cmd
86+
.status()
87+
.expect("failed to run objcopy to strip debug symbols");
88+
if !exit_status.success() {
89+
eprintln!("Error: Stripping debug symbols failed");
90+
process::exit(1);
91+
}
92+
93+
// wrap the kernel executable as binary in a new ELF file
94+
let stripped_kernel_file_name_replaced = stripped_kernel_file_name.replace('-', "_");
95+
let kernel_bin = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
96+
let kernel_archive = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));
97+
let mut cmd = Command::new(&objcopy);
8498
cmd.arg("-I").arg("binary");
8599
cmd.arg("-O").arg("elf64-x86-64");
86100
cmd.arg("--binary-architecture=i386:x86-64");
87101
cmd.arg("--rename-section").arg(".data=.kernel");
88102
cmd.arg("--redefine-sym").arg(format!(
89103
"_binary_{}_start=_kernel_start_addr",
90-
kernel_file_name_replaced
104+
stripped_kernel_file_name_replaced
91105
));
92106
cmd.arg("--redefine-sym").arg(format!(
93107
"_binary_{}_end=_kernel_end_addr",
94-
kernel_file_name_replaced
108+
stripped_kernel_file_name_replaced
95109
));
96110
cmd.arg("--redefine-sym").arg(format!(
97111
"_binary_{}_size=_kernel_size",
98-
kernel_file_name_replaced
112+
stripped_kernel_file_name_replaced
99113
));
100-
cmd.current_dir(kernel.parent().expect("KERNEL has no valid parent dir"));
101-
cmd.arg(&kernel_file_name);
102-
cmd.arg(&kernel_out_path);
114+
cmd.current_dir(&out_dir);
115+
cmd.arg(&stripped_kernel_file_name);
116+
cmd.arg(&kernel_bin);
103117
let exit_status = cmd.status().expect("failed to run objcopy");
104118
if !exit_status.success() {
105119
eprintln!("Error: Running objcopy failed");
@@ -117,8 +131,8 @@ fn main() {
117131
});
118132
let mut cmd = Command::new(ar);
119133
cmd.arg("crs");
120-
cmd.arg(&kernel_archive_path);
121-
cmd.arg(&kernel_out_path);
134+
cmd.arg(&kernel_archive);
135+
cmd.arg(&kernel_bin);
122136
let exit_status = cmd.status().expect("failed to run ar");
123137
if !exit_status.success() {
124138
eprintln!("Error: Running ar failed");

0 commit comments

Comments
 (0)