Skip to content

Commit cf9517f

Browse files
committed
wip
1 parent 2f3bd08 commit cf9517f

File tree

17 files changed

+264
-108
lines changed

17 files changed

+264
-108
lines changed

real_mode/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ edition = "2018"
99
[dependencies]
1010

1111
[profile.release]
12-
opt-level = "z"
12+
opt-level = "s"
1313
lto = true
1414
debug = true
15+
codegen-units = 1

real_mode/build.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use std::process::Command;
2+
use std::env;
3+
use std::fs::{self, File};
4+
use std::path::Path;
5+
6+
fn main() {
7+
let out_dir = env::var("OUT_DIR").unwrap();
8+
9+
// first stage
10+
let mut cmd = Command::new("cargo");
11+
cmd.arg("xbuild").arg("--release");
12+
cmd.arg("--manifest-path=first_stage/Cargo.toml");
13+
cmd.arg("-Z").arg("unstable-options");
14+
cmd.arg("--out-dir").arg(&out_dir);
15+
let status = cmd.status().unwrap();
16+
assert!(status.success());
17+
18+
// second stage
19+
let mut cmd = Command::new("cargo");
20+
cmd.arg("xbuild").arg("--release");
21+
cmd.arg("--manifest-path=second_stage/Cargo.toml");
22+
cmd.arg("-Z").arg("unstable-options");
23+
cmd.arg("--out-dir").arg(&out_dir);
24+
let status = cmd.status().unwrap();
25+
assert!(status.success());
26+
27+
let concat_script = Path::new(&out_dir).join("concat.mri");
28+
fs::write(&concat_script, "
29+
create libreal_mode.a
30+
addlib libfirst_stage.a
31+
addlib libsecond_stage.a
32+
save
33+
end
34+
").unwrap();
35+
36+
// concat archives
37+
let mut cmd = Command::new("ar");
38+
cmd.arg("-M").stdin(File::open(concat_script).unwrap());
39+
cmd.current_dir(&out_dir);
40+
let status = cmd.status().unwrap();
41+
assert!(status.success());
42+
43+
println!("cargo:rustc-link-search=native={}", out_dir);
44+
println!("cargo:rustc-link-lib=static=real_mode");
45+
}

real_mode/first_stage/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

real_mode/first_stage/Cargo.lock

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

real_mode/first_stage/Cargo.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "first_stage"
3+
version = "0.1.0"
4+
authors = ["Philipp Oppermann <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[lib]
10+
name = "first_stage"
11+
crate-type = ["staticlib"]
12+
13+
[dependencies]
14+
15+
16+
[profile.release]
17+
opt-level = "s"
18+
lto = true
19+
codegen-units = 1
20+
debug = true

real_mode/src/boot.s renamed to real_mode/first_stage/src/boot.s

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,19 @@ check_int13h_extensions:
7474
jc no_int13h_extensions
7575

7676
rust:
77-
push dx # pass disk number as argument
78-
call rust_main
77+
# push arguments
78+
arg_0:
79+
push dx # disk number
80+
lea eax, _bootloader_start
81+
arg_1:
82+
push eax
83+
lea eax, _second_stage_end
84+
arg_2:
85+
push eax
86+
lea eax, _second_stage_start
87+
arg_3:
88+
push eax
89+
call first_stage
7990

8091
spin:
8192
hlt
File renamed without changes.

real_mode/first_stage/src/lib.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#![feature(asm, global_asm)]
2+
#![no_std]
3+
4+
global_asm!(include_str!("boot.s"));
5+
6+
mod dap;
7+
8+
extern "C" {
9+
fn second_stage(disk_number: u16);
10+
}
11+
12+
/// Test function
13+
#[no_mangle]
14+
pub extern "C" fn first_stage(second_stage_start: u32, second_stage_end: u32, bootloader_start: u32, disk_number: u16) {
15+
load_second_stage(second_stage_start, second_stage_end, bootloader_start, disk_number);
16+
unsafe { second_stage(disk_number); }
17+
}
18+
19+
fn load_second_stage(second_stage_start: u32, second_stage_end: u32, bootloader_start: u32, disk_number: u16) {
20+
use dap::DiskAddressPacket;
21+
22+
let file_offset = (second_stage_start - bootloader_start) as u64;
23+
let size = (second_stage_end - second_stage_start) as u32;
24+
25+
let dap = DiskAddressPacket::new(second_stage_start as u16, file_offset, size);
26+
unsafe { dap.perform_load(disk_number) }
27+
}
28+
29+
#[no_mangle]
30+
pub extern fn print_char(c: u8) {
31+
let ax = u16::from(c) | 0x0e00;
32+
unsafe {
33+
asm!("int 0x10" :: "{ax}"(ax), "{bx}"(0) :: "intel" );
34+
}
35+
}
36+
37+
#[no_mangle]
38+
pub extern "C" fn dap_load_failed() -> ! {
39+
err(b'1');
40+
}
41+
42+
#[no_mangle]
43+
pub extern "C" fn no_int13h_extensions() -> ! {
44+
err(b'2');
45+
}
46+
47+
#[cold]
48+
fn err(code: u8) -> ! {
49+
for &c in b"Err:" {
50+
print_char(c);
51+
}
52+
print_char(code);
53+
loop {
54+
hlt()
55+
}
56+
}
57+
58+
fn hlt() {
59+
unsafe {
60+
asm!("hlt":::: "intel","volatile");
61+
}
62+
}
63+
64+
#[panic_handler]
65+
pub fn panic(_info: &core::panic::PanicInfo) -> ! {
66+
err(b'P');
67+
}
68+

real_mode/linker.ld

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ SECTIONS {
1111
{
1212
*(.boot)
1313
}
14-
.text :
14+
.first_stage_text :
1515
{
16-
*(.text .text.*)
16+
*first_stage*(.text .text.*)
1717
}
18-
.data :
18+
.first_stage_data :
1919
{
20-
*(.rodata .rodata.*)
21-
*(.data .data.*)
22-
*(.got)
20+
*first_stage*(.rodata .rodata.*)
21+
*first_stage*(.data .data.*)
22+
*first_stage*(.got .got.*)
2323
}
2424

2525
. = 0x7c00 + 510;
@@ -29,7 +29,31 @@ SECTIONS {
2929
}
3030

3131
_second_stage_start = .;
32-
.second_stage :
32+
33+
.second_stage_text :
34+
{
35+
*second_stage*(.text .text.*)
36+
}
37+
.second_stage_data :
38+
{
39+
*second_stage*(.rodata .rodata.*)
40+
*second_stage*(.data .data.*)
41+
*second_stage*(.got .got.*)
42+
}
43+
44+
.text :
45+
{
46+
*(.text .text.*)
47+
}
48+
49+
.data :
50+
{
51+
*(.rodata .rodata.*)
52+
*(.data .data.*)
53+
*(.got .got.*)
54+
}
55+
56+
.asm :
3357
{
3458
*(.second_stage)
3559
}

real_mode/second_stage/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

0 commit comments

Comments
 (0)