Skip to content

Commit 3f6ff29

Browse files
[Rewrite] Architecture Subcrates
Implement architecture-specific subcrates
2 parents 87673c8 + 4be2082 commit 3f6ff29

File tree

29 files changed

+336
-215
lines changed

29 files changed

+336
-215
lines changed

.cargo/config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
[build]
2+
target = "i8086-bootloader.json"
3+
14
[alias]
25
xbuild = "build -Zbuild-std=core"

.github/workflows/build.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,9 @@ jobs:
4646

4747
- name: 'Build Bootloader'
4848
run: cargo xbuild --release
49-
working-directory: src/stage_2
5049

5150
- name: 'Convert Bootloader ELF to Binary'
52-
run: cargo objcopy -- -I elf64-i386 -O binary --binary-architecture=i386:x86-64 target/x86_64-real_mode/release/stage_2 target/x86_64-real_mode/release/image.bin
51+
run: cargo objcopy -- -I elf64-i386 -O binary --binary-architecture=i386:x86-64 target/i8086-bootloader/release/bootloader target/i8086-bootloader/release/image.bin
5352

5453
# # install QEMU
5554
# - name: Install QEMU (Linux)

Cargo.lock

Lines changed: 8 additions & 105 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
[workspace]
2-
members = [
3-
"src/shared",
4-
"src/v86",
5-
"src/bootsector",
6-
"src/stage_2",
7-
"example-kernel",
8-
"test-kernel",
9-
]
1+
[package]
2+
name = "bootloader"
3+
version = "0.1.0"
4+
authors = ["Ryland Morgan <[email protected]>"]
5+
edition = "2018"
6+
build = "build.rs"
107

11-
[profile.release]
12-
opt-level = "z"
13-
panic = "abort"
14-
lto = true
8+
[dependencies]
9+
shared = { path = "src/shared" }
1510

16-
[profile.release.package.bootsector]
17-
opt-level = "s"
18-
codegen-units = 1
11+
[build-dependencies]
12+
llvm-tools = "0.1"

build.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// This build script compiles our bootloader. Because of architecture differences we can't use the standard Rust dependency resolution. To get around this (and add some more seperation between different areas) we compile all of the subcrates as static libraries and link them like we would a C dependency
2+
3+
// TODO - Reuse compilation artifacts so core isn't compiled so many times
4+
use llvm_tools::{exe, LlvmTools};
5+
use std::env;
6+
use std::path::Path;
7+
use std::process::Command;
8+
9+
fn main() {
10+
// Read environment variables set by cargo
11+
let out_dir_path = env::var("OUT_DIR").expect("Missing OUT_DIR environment variable");
12+
let out_dir = Path::new(&out_dir_path);
13+
14+
let cargo_path = env::var("CARGO").expect("Missing CARGO environment variable");
15+
let cargo = Path::new(&cargo_path);
16+
17+
let manifest_dir_path =
18+
env::var("CARGO_MANIFEST_DIR").expect("Missing CARGO_MANIFEST_DIR environment variable");
19+
let manifest_dir = Path::new(&manifest_dir_path);
20+
21+
// Find the objcopy binary
22+
let llvm_tools = LlvmTools::new().expect("LLVM tools not found");
23+
let objcopy = llvm_tools
24+
.tool(&exe("llvm-objcopy"))
25+
.expect("llvm-objcopy not found");
26+
27+
// Build the bootsector
28+
build_subproject(
29+
Path::new("src/real/bootsector"),
30+
&[
31+
"_start",
32+
"real_mode_println",
33+
"no_int13h_extensions",
34+
"dap_load_failed",
35+
],
36+
"../i8086-real_mode.json",
37+
&out_dir,
38+
&objcopy,
39+
&cargo,
40+
);
41+
42+
// Build stage 2
43+
build_subproject(
44+
Path::new("src/real/stage_2"),
45+
&["second_stage"],
46+
"../i8086-real_mode.json",
47+
&out_dir,
48+
&objcopy,
49+
&cargo,
50+
);
51+
}
52+
53+
fn build_subproject(
54+
subproject_dir: &Path,
55+
global_symbols: &[&str],
56+
target_file_path: &str,
57+
root_out_dir: &Path,
58+
objcopy: &Path,
59+
cargo: &Path,
60+
) {
61+
let subproject_name = subproject_dir
62+
.file_stem()
63+
.expect("Couldn't get subproject name")
64+
.to_str()
65+
.expect("Subproject Name is not valid UTF-8");
66+
let target_file = Path::new(&target_file_path)
67+
.file_stem()
68+
.expect("Couldn't get target file stem");
69+
let target_dir = root_out_dir.join("target").join(&subproject_name);
70+
71+
// We have to export at least 1 symbol
72+
assert!(
73+
global_symbols.len() > 0,
74+
"must have at least one global symbol"
75+
);
76+
77+
// Use cargo in CARGO environment variable (set on build)
78+
let mut build_cmd = Command::new(cargo);
79+
80+
// Build inside the subproject
81+
build_cmd.current_dir(&subproject_dir);
82+
83+
// Build in release mode
84+
build_cmd.arg("build").arg("--release");
85+
86+
// Cross-compile core (cargo-xbuild no longer needed)
87+
build_cmd.arg("-Zbuild-std=core");
88+
89+
// Use calculated target directory
90+
build_cmd.arg(format!("--target-dir={}", &target_dir.display()));
91+
92+
// Use the passed target
93+
build_cmd.arg("--target").arg(target_file_path);
94+
95+
// Run the command and make sure it succeeds
96+
let build_status = build_cmd.status().expect("Subcrate build failed!");
97+
assert!(build_status.success(), "Subcrate build failed!");
98+
99+
// Compute the path to the binary
100+
let binary_dir = target_dir.join(&target_file).join("release");
101+
let binary_path = binary_dir.join(format!("lib{}.a", &subproject_name));
102+
103+
// Use passed objcopy
104+
let mut objcopy_cmd = Command::new(objcopy);
105+
106+
// Localize all symbols except those passed
107+
for symbol in global_symbols {
108+
objcopy_cmd.arg("-G").arg(symbol);
109+
}
110+
111+
// Pass the binary as argument
112+
objcopy_cmd.arg(binary_path);
113+
114+
// Run the command and make sure it succeeds
115+
let objcopy_status = objcopy_cmd.status().expect("Objcopy failed!");
116+
assert!(objcopy_status.success(), "Objcopy failed!");
117+
118+
// Emit flags to the linker
119+
//
120+
// Staticlibs can't be used as normal dependencies, they have to be linked by a build script
121+
println!("cargo:rustc-link-search=native={}", &binary_dir.display());
122+
println!("cargo:rustc-link-lib=static={}", &subproject_name);
123+
}

i8086-bootloader.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"arch": "x86",
3+
"cpu": "i386",
4+
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
5+
"dynamic-linking": false,
6+
"executables": true,
7+
"linker-flavor": "ld.lld",
8+
"linker": "rust-lld",
9+
"llvm-target": "i386-unknown-none-code16",
10+
"max-atomic-width": 64,
11+
"position-independent-executables": false,
12+
"disable-redzone": true,
13+
"target-c-int-width": "32",
14+
"target-pointer-width": "32",
15+
"target-endian": "little",
16+
"panic-strategy": "abort",
17+
"os": "none",
18+
"vendor": "unknown",
19+
"relocation_model": "static",
20+
"eliminate_frame_pointer": true,
21+
"pre-link-args": {
22+
"ld.lld": [
23+
"--script=src/real/linker.ld"
24+
]
25+
}
26+
}

src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
mod panic;
5+
6+
#[no_mangle]
7+
fn bootloader_no_optimize() {}
File renamed without changes.

src/v86/Cargo.toml renamed to src/protected/v86/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,3 @@ authors = ["Ryland Morgan <[email protected]>"]
55
edition = "2018"
66

77
[dependencies]
8-
bitflags = "1.2.1"
9-
bit_field = "0.10.0"

src/v86/src/lib.rs renamed to src/protected/v86/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
#![feature(abi_x86_interrupt)]
2-
#![feature(const_fn)]
3-
#![feature(llvm_asm)]
41
#![no_std]
2+
53
// FIXME
64
#![allow(dead_code, unused_imports)]
75

86
use core::slice;
97

10-
pub mod gdt;
11-
pub mod idt;
12-
138
const EFLAG_IF: u32 = 0x00000200;
149
const EFLAG_VM: u32 = 0x00020000;
10+
1511
/*
1612
pub struct V86 {}
1713

0 commit comments

Comments
 (0)