Skip to content

Commit

Permalink
Merge #59
Browse files Browse the repository at this point in the history
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 <dev@phil-opp.com>
  • Loading branch information
bors[bot] and phil-opp committed Jun 24, 2019
2 parents 12645da + e536942 commit d2512aa
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 19 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- Make the physical memory offset configurable through a `BOOTLOADER_PHYSICAL_MEMORY_OFFSET` environment variable ([#58](https://github.com/rust-osdev/bootloader/pull/58)).
- Use a stripped copy of the kernel binary (debug info removed) to reduce load times ([#59](https://github.com/rust-osdev/bootloader/pull/59)).

# 0.6.0

Expand Down
52 changes: 33 additions & 19 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,18 @@ fn main() {
process::exit(1);
}
});
let kernel_file_name = kernel
.file_name()
.expect("KERNEL has no valid file name")
.to_str()
.expect("kernel file name not valid utf8");

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

let kernel_file_name = kernel
.file_name()
.expect("KERNEL has no valid file name")
.to_str()
.expect("kernel file name not valid utf8");
let kernel_file_name_replaced = kernel_file_name.replace('-', "_");
let kernel_out_path = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
let kernel_archive_path = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));

// get access to llvm tools shipped in the llvm-tools-preview rustup component
let llvm_tools = match llvm_tools::LlvmTools::new() {
Ok(tools) => tools,
Expand Down Expand Up @@ -76,30 +72,48 @@ fn main() {
Kernel executable at `{}`\n", kernel.display());
}

// wrap the kernel executable as binary in a new ELF file
// strip debug symbols from kernel for faster loading
let stripped_kernel_file_name = format!("kernel_stripped-{}", kernel_file_name);
let stripped_kernel = out_dir.join(&stripped_kernel_file_name);
let objcopy = llvm_tools
.tool(&llvm_tools::exe("llvm-objcopy"))
.expect("llvm-objcopy not found in llvm-tools");
let mut cmd = Command::new(objcopy);
let mut cmd = Command::new(&objcopy);
cmd.arg("--strip-debug");
cmd.arg(&kernel);
cmd.arg(&stripped_kernel);
let exit_status = cmd
.status()
.expect("failed to run objcopy to strip debug symbols");
if !exit_status.success() {
eprintln!("Error: Stripping debug symbols failed");
process::exit(1);
}

// wrap the kernel executable as binary in a new ELF file
let stripped_kernel_file_name_replaced = stripped_kernel_file_name.replace('-', "_");
let kernel_bin = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
let kernel_archive = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));
let mut cmd = Command::new(&objcopy);
cmd.arg("-I").arg("binary");
cmd.arg("-O").arg("elf64-x86-64");
cmd.arg("--binary-architecture=i386:x86-64");
cmd.arg("--rename-section").arg(".data=.kernel");
cmd.arg("--redefine-sym").arg(format!(
"_binary_{}_start=_kernel_start_addr",
kernel_file_name_replaced
stripped_kernel_file_name_replaced
));
cmd.arg("--redefine-sym").arg(format!(
"_binary_{}_end=_kernel_end_addr",
kernel_file_name_replaced
stripped_kernel_file_name_replaced
));
cmd.arg("--redefine-sym").arg(format!(
"_binary_{}_size=_kernel_size",
kernel_file_name_replaced
stripped_kernel_file_name_replaced
));
cmd.current_dir(kernel.parent().expect("KERNEL has no valid parent dir"));
cmd.arg(&kernel_file_name);
cmd.arg(&kernel_out_path);
cmd.current_dir(&out_dir);
cmd.arg(&stripped_kernel_file_name);
cmd.arg(&kernel_bin);
let exit_status = cmd.status().expect("failed to run objcopy");
if !exit_status.success() {
eprintln!("Error: Running objcopy failed");
Expand All @@ -117,8 +131,8 @@ fn main() {
});
let mut cmd = Command::new(ar);
cmd.arg("crs");
cmd.arg(&kernel_archive_path);
cmd.arg(&kernel_out_path);
cmd.arg(&kernel_archive);
cmd.arg(&kernel_bin);
let exit_status = cmd.status().expect("failed to run ar");
if !exit_status.success() {
eprintln!("Error: Running ar failed");
Expand Down

0 comments on commit d2512aa

Please sign in to comment.