Skip to content

Rewrite build system #51

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

Merged
merged 10 commits into from
Apr 1, 2019
Merged
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
target = "x86_64-bootloader.json"
45 changes: 0 additions & 45 deletions .travis.yml

This file was deleted.

7 changes: 7 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ description = "An experimental pure-Rust x86 bootloader."
repository = "https://github.com/rust-osdev/bootloader"
publish-lockfile = true
edition = "2018"
build = "build.rs"

[dependencies]
xmas-elf = "0.6.2"
@@ -21,6 +22,9 @@ version = "0.2.4"
default-features = false
features = ["unicode"]

[build-dependencies]
llvm-tools = "0.1"

[features]
default = []
vga_320x200 = []
27 changes: 10 additions & 17 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -10,8 +10,6 @@ trigger:
- trying
# Build pull requests.
- master
# Build post braches
- post-*

strategy:
matrix:
@@ -64,11 +62,11 @@ steps:
displayName: 'Print Rust Version'
continueOnError: true

- script: rustup component add rust-src
displayName: 'Install Rustup Src Component'
- script: rustup component add rust-src llvm-tools-preview
displayName: 'Install Rustup Components'

- script: cargo install cargo-xbuild bootimage --debug
displayName: 'Install cargo-xbuild and bootimage'
- script: cargo install cargo-xbuild cargo-binutils --debug
displayName: 'Install cargo-xbuild cargo-binutils'

- script: sudo apt update && sudo apt install qemu-system-x86
condition: eq( variables['Agent.OS'], 'Linux' )
@@ -96,20 +94,15 @@ steps:
workingDirectory: example-kernel
displayName: 'Build Example Kernel'

- script: cargo run -- --kernel ../example-kernel/target/x86_64-example-kernel/debug/example-kernel
workingDirectory: builder
- script: cargo xbuild --release
displayName: 'Build Bootloader'
env: { KERNEL: "example-kernel/target/x86_64-example-kernel/debug/example-kernel" }

- script: cargo objcopy -- -I elf64-x86-64 -O binary --binary-architecture=i386:x86-64 target/x86_64-bootloader/release/bootloader target/x86_64-bootloader/release/bootloader.bin
displayName: 'Convert Bootloader ELF to Binary'

- bash: |
qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootloader/release/bootimage.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none
qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootloader/release/bootloader.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none
if [ $? -eq 123 ]; then (exit 0); else (exit 1); fi
displayName: 'Test Bootloader'

- script: cargo run -- --kernel ../example-kernel/target/x86_64-example-kernel/debug/example-kernel --features vga_320x200
workingDirectory: builder
displayName: 'Build Bootloader (Feature vga_320x200)'

- bash: |
qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootloader/release/bootimage.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none
if [ $? -eq 123 ]; then (exit 0); else (exit 1); fi
displayName: 'Test Bootloader (Feature vga_320x200)'
82 changes: 82 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use std::{env, path::{Path, PathBuf}, process::{self, Command}};

fn main() {
let target = env::var("TARGET").expect("TARGET not set");
if Path::new(&target)
.file_stem()
.expect("target has no file stem")
!= "x86_64-bootloader"
{
return;
}

let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
let kernel = PathBuf::from(match env::var("KERNEL") {
Ok(kernel) => kernel,
Err(_) => {
eprintln!(
"The KERNEL environment variable must be set for building the bootloader."
);
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");
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));

let llvm_tools = match llvm_tools::LlvmTools::new() {
Ok(tools) => tools,
Err(llvm_tools::Error::NotFound) => {
eprintln!("Error: llvm-tools not found");
eprintln!("Maybe the rustup component `llvm-tools-preview` is missing?");
eprintln!(" Install it through: `rustup component add llvm-tools-preview`");
process::exit(1);
}
Err(err) => {
eprintln!("Failed to retrieve llvm-tools component: {:?}", err);
process::exit(1);
}
};
let objcopy = llvm_tools.tool(&llvm_tools::exe("llvm-objcopy")).expect("llvm-objcopy not found in llvm-tools");

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));
cmd.arg("--redefine-sym").arg(format!("_binary_{}_end=_kernel_end_addr", kernel_file_name_replaced));
cmd.arg("--redefine-sym").arg(format!("_binary_{}_size=_kernel_size", 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);
let exit_status = cmd.status().expect("failed to run objcopy");
if !exit_status.success() {
eprintln!("Error: Running objcopy failed");
process::exit(1);
}

let ar = llvm_tools.tool(&llvm_tools::exe("llvm-ar")).unwrap_or_else(|| {
eprintln!("Failed to retrieve llvm-ar component");
eprint!("This component is available since nightly-XXXX-XX-XX,");
eprintln!("so try updating your toolchain if you're using an older nightly");
process::exit(1);
});
let mut cmd = Command::new(ar);
cmd.arg("crs");
cmd.arg(&kernel_archive_path);
cmd.arg(&kernel_out_path);
let exit_status = cmd.status().expect("failed to run ar");
if !exit_status.success() {
eprintln!("Error: Running ar failed");
process::exit(1);
}

println!("cargo:rerun-if-env-changed=KERNEL");
println!("cargo:rerun-if-changed={}", kernel.display());
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-link-search=native={}", out_dir.display());
println!("cargo:rustc-link-lib=static=kernel_bin-{}", kernel_file_name);
}
2 changes: 0 additions & 2 deletions builder/.gitignore

This file was deleted.

74 changes: 0 additions & 74 deletions builder/Cargo.lock

This file was deleted.

11 changes: 0 additions & 11 deletions builder/Cargo.toml

This file was deleted.

224 changes: 0 additions & 224 deletions builder/src/main.rs

This file was deleted.

12 changes: 5 additions & 7 deletions linker.ld
Original file line number Diff line number Diff line change
@@ -40,13 +40,11 @@ SECTIONS {
*(.got)
. = ALIGN(512);
_rest_of_bootloader_end_addr = .;
__bootloader_end = .;
}

_kernel_info_block_start = .;
_kib_kernel_size = .;
. += 512; /* kernel info block */
_kernel_info_block_end = .;

__bootloader_end = .;
_kernel_start_addr = .;
.kernel :
{
KEEP(*(.kernel))
}
}
9 changes: 7 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,9 @@
#![no_std]
#![no_main]

#[cfg(not(target_os = "none"))]
compile_error!("The bootloader crate must be compiled for the `x86_64-bootloader.json` target");

use bootloader::bootinfo::{BootInfo, FrameRange};
use core::panic::PanicInfo;
use core::{mem, slice};
@@ -63,7 +66,9 @@ impl IdentityMappedAddr {
extern "C" {
static mmap_ent: usize;
static _memory_map: usize;
static _kib_kernel_size: usize;
static _kernel_start_addr: usize;
static _kernel_end_addr: usize;
static _kernel_size: usize;
static __page_table_start: usize;
static __page_table_end: usize;
static __bootloader_end: usize;
@@ -77,7 +82,7 @@ pub unsafe extern "C" fn stage_4() -> ! {
mov ss, bx" ::: "bx" : "intel");

let kernel_start = 0x400000;
let kernel_size = _kib_kernel_size as u64;
let kernel_size = &_kernel_size as *const _ as u64;
let memory_map_addr = &_memory_map as *const _ as u64;
let memory_map_entry_count = (mmap_ent & 0xff) as u64; // Extract lower 8 bits
let page_table_start = &__page_table_start as *const _ as u64;
2 changes: 1 addition & 1 deletion src/stage_1.s
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ load_rest_of_bootloader_from_disk:
mov [dap_buffer_addr], ax

# number of disk blocks to load
lea ebx, _kernel_info_block_end
lea ebx, _rest_of_bootloader_end_addr
sub ebx, eax # end - start
shr ebx, 9 # divide by 512 (block size)
mov [dap_blocks], bx
2 changes: 1 addition & 1 deletion src/stage_2.s
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ load_kernel_from_disk:
mov edi, 0x400000

# block count
mov ecx, _kib_kernel_size
lea ecx, _kernel_size
add ecx, 511 # align up
shr ecx, 9

2 changes: 1 addition & 1 deletion src/stage_3.s
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ set_up_page_tables:
mov [_p2], eax
mov eax, (0x400000 | 1 | 2 | (1 << 7))
mov ecx, 2
mov edx, _kib_kernel_size
lea edx, _kernel_size
add edx, 0x400000 # start address
add edx, 0x200000 - 1 # align up
shr edx, 12 + 9 # end huge page number