Skip to content

Commit 31f9154

Browse files
everywhere: initial support for aarch64
* Everything for aarch64 is stubbed now and prints a welcoming Hello, World message. * Updated the build script to work for aarch64 UEFI * UART MMIO32 templated * Fix the doomgeneric patch * Add cfg-if for a bunch of #[cfg] helper macros Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
1 parent 2c09a51 commit 31f9154

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+530
-231
lines changed

aero.py

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,29 @@
7272
"""
7373

7474

75+
class BuildInfo:
76+
args: argparse.Namespace
77+
target_arch: str
78+
79+
def __init__(self, target_arch: str, args: argparse.Namespace):
80+
self.target_arch = target_arch
81+
self.args = args
82+
83+
7584
def log_info(msg):
7685
"""
7786
Logs a message with info log level.
7887
"""
7988
print(f"\033[1m\033[92minfo\033[0m: {msg}")
8089

8190

91+
def log_error(msg):
92+
"""
93+
Logs a message with error log level.
94+
"""
95+
print(f"\033[1m\033[91merror\033[0m: {msg}")
96+
97+
8298
def download_userland_host_rust():
8399
out_file = os.path.join(BUNDLED_DIR, "host-rust-prebuilt.tar.gz")
84100

@@ -162,7 +178,7 @@ def parse_args():
162178
default=False,
163179
action='store_true',
164180
help='doesn\'t run the built image in emulator when applicable')
165-
181+
166182
parser.add_argument('--only-run',
167183
default=False,
168184
action='store_true',
@@ -365,6 +381,7 @@ def get_binutils(): return os.path.join("..", tool_dir, HOST_BINUTILS)
365381
def get_mlibc(): return os.path.join("..", pkg_dir, PACKAGE_MLIBC)
366382

367383
command = 'build'
384+
# TODO: handle the unbased architectures.
368385
cmd_args = ["--target", "x86_64-unknown-aero-system",
369386

370387
# cargo config
@@ -423,6 +440,12 @@ def prepare_iso(args, kernel_bin, user_bins):
423440
shutil.copy(os.path.join(limine_path, 'limine-cd.bin'), iso_root)
424441
shutil.copy(os.path.join(limine_path, 'limine-cd-efi.bin'), iso_root)
425442

443+
efi_boot = os.path.join(iso_root, "EFI", "BOOT")
444+
os.makedirs(efi_boot)
445+
446+
shutil.copy(os.path.join(limine_path, 'BOOTAA64.EFI'), efi_boot)
447+
shutil.copy(os.path.join(limine_path, 'BOOTX64.EFI'), efi_boot)
448+
426449
sysroot_dir = os.path.join(SYSROOT_DIR, 'system-root')
427450
shutil.copytree(BASE_FILES_DIR, sysroot_dir, dirs_exist_ok=True)
428451

@@ -452,7 +475,7 @@ def find(path) -> List[str]:
452475
files = list(files_without_prefix)
453476

454477
files.append("usr/lib/libiconv.so.2")
455-
return files
478+
return files
456479

457480
files = find(sysroot_dir)
458481

@@ -474,8 +497,8 @@ def find(path) -> List[str]:
474497
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
475498

476499
if code != 0:
477-
print('Failed to create the ISO image')
478-
print(xorriso_stderr.decode('utf-8'))
500+
log_error('failed to create the ISO image')
501+
log_error(xorriso_stderr.decode('utf-8'))
479502

480503
return None
481504

@@ -486,34 +509,40 @@ def find(path) -> List[str]:
486509
stdout=subprocess.PIPE,
487510
stderr=subprocess.PIPE)
488511
if code != 0:
489-
print('Failed to build `limine-deploy`')
490-
print(limine_build_stderr.decode('utf8'))
512+
log_error('failed to build `limine-deploy`')
513+
log_error(limine_build_stderr.decode('utf8'))
491514
exit(1)
492515

493516
code, _, limine_deploy_stderr = run_command([limine_deploy, iso_path],
494517
stdout=subprocess.PIPE,
495518
stderr=subprocess.PIPE)
496519

497520
if code != 0:
498-
print('Failed to install Limine')
499-
print(limine_deploy_stderr)
521+
log_error('failed to install Limine')
522+
log_error(limine_deploy_stderr)
500523

501524
return None
502525

503526
return iso_path
504527

505528

506-
def run_in_emulator(args, iso_path):
529+
def run_in_emulator(build_info: BuildInfo, iso_path):
507530
is_kvm_available = is_kvm_supported()
531+
args = build_info.args
508532

509533
qemu_args = ['-cdrom', iso_path,
510-
'-M', 'q35',
511534
'-m', '9800M',
512535
'-smp', '1',
513536
'-serial', 'stdio']
514537

515538
if args.bios == 'uefi':
516-
qemu_args += ['-bios', 'bundled/ovmf/OVMF-pure-efi.fd']
539+
if build_info.target_arch == "aarch64":
540+
qemu_args += ['-bios', 'bundled/ovmf/OVMF.fd']
541+
elif build_info.target_arch == "x86_64":
542+
qemu_args += ['-bios', 'bundled/ovmf/OVMF-pure-efi.fd']
543+
else:
544+
log_error("unknown target architecture")
545+
exit(1)
517546

518547
cmdline = args.remaining
519548

@@ -524,7 +553,7 @@ def run_in_emulator(args, iso_path):
524553
qemu_args += cmdline
525554

526555
if is_kvm_available and not args.disable_kvm:
527-
print("Running with KVM acceleration enabled")
556+
log_info("running with KVM acceleration enabled")
528557

529558
if platform.system() == 'Darwin':
530559
qemu_args += ['-accel', 'hvf', '-cpu',
@@ -533,9 +562,17 @@ def run_in_emulator(args, iso_path):
533562
qemu_args += ['-enable-kvm', '-cpu',
534563
'host,+la57' if args.la57 else 'host']
535564
else:
536-
qemu_args += ["-cpu", "qemu64,+la57" if args.la57 else "qemu64"]
565+
if build_info.target_arch == "aarch64":
566+
qemu_args += ['-device', 'ramfb',
567+
'-M', 'virt', '-cpu', 'cortex-a72']
568+
elif build_info.target_arch == "x86_64":
569+
qemu_args += ["-cpu", "qemu64,+la57" if args.la57 else "qemu64"]
570+
else:
571+
log_error("unknown target architecture")
572+
exit(1)
537573

538-
run_command(['qemu-system-x86_64', *qemu_args])
574+
qemu_binary = f'qemu-system-{build_info.target_arch}'
575+
run_command([qemu_binary, *qemu_args])
539576

540577

541578
def get_sysctl(name: str) -> str:
@@ -620,6 +657,14 @@ def is_kvm_supported() -> bool:
620657
def main():
621658
args = parse_args()
622659

660+
# arch-aero_os
661+
target_arch = args.target.split('-')[0]
662+
build_info = BuildInfo(target_arch, args)
663+
664+
if build_info.target_arch == "aarch64" and not args.bios == "uefi":
665+
log_error("aarch64 requires UEFI (help: run again with `--bios=uefi`)")
666+
return
667+
623668
download_bundled()
624669

625670
if args.only_run:
@@ -669,7 +714,7 @@ def main():
669714
iso_path = prepare_iso(args, kernel_bin, user_bins)
670715

671716
if not args.no_run:
672-
run_in_emulator(args, iso_path)
717+
run_in_emulator(build_info, iso_path)
673718

674719

675720
if __name__ == '__main__':

bochsrc.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ clock: sync=realtime, rtc_sync=1, time0=local
99
cpu: count=4, reset_on_triple_fault=0, model=corei7_haswell_4770, ips=10000000
1010
cpuid: 1g_pages=0, apic=x2apic
1111
debug: action=report
12-
ata0-master: type=disk, path="build/aero.img", mode=flat
12+
ata0-master: type=disk, path="build/aero.iso", mode=flat
1313
plugin_ctrl: e1000=1
1414
e1000: enabled=0, mac=fe:fd:de:ad:be:ef, ethmod=null

patches/doomgeneric/doomgeneric.patch

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,11 +570,11 @@ index 0000000..1172db3
570570
+ log_info("initializing framebuffer");
571571
+
572572
+ // Open up the framebuffer device.
573-
+ size_t framebuffer = fopen("/dev/fb", "r+");
573+
+ size_t framebuffer = fopen("/dev/fb0", "r+");
574574
+
575575
+ // Make sure the there were no errors.
576576
+ if (framebuffer == NULL) {
577-
+ log_error("failed to open `/dev/fb`");
577+
+ log_error("failed to open `/dev/fb0`");
578578
+ exit(1);
579579
+ }
580580
+

src/.cargo/aarch64-aero_os.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,11 @@
1111
"linker": "rust-lld",
1212
"panic-strategy": "abort",
1313
"disable-redzone": true,
14-
"features": "+strict-align,-neon,-fp-armv8"
14+
"features": "+strict-align,-neon,-fp-armv8",
15+
"pre-link-args": {
16+
"ld.lld": [
17+
"--gc-sections",
18+
"--script=.cargo/kernel.ld"
19+
]
20+
}
1521
}

src/.cargo/kernel.ld

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
/* Tell the linker that we want an x86_64 ELF64 output file */
2-
OUTPUT_FORMAT(elf64-x86-64)
3-
OUTPUT_ARCH(i386:x86-64)
4-
5-
/* We want the symbol `x86_64_aero_main` to be our entry point */
6-
ENTRY(x86_64_aero_main)
1+
/* We want the symbol `arch_aero_main` to be our entry point */
2+
ENTRY(arch_aero_main)
73

84
/* Define the program headers we want so the bootloader gives us the right */
95
/* MMU permissions */

src/Cargo.lock

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

src/aero_kernel/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ kmemleak = []
2020
vmlog = []
2121
syslog = []
2222

23+
2324
default = ["round-robin"]
2425

2526
[dependencies]
@@ -31,9 +32,8 @@ spin = { version = "0.9.4", default-features = false, features = [
3132
bitflags = "1.2.1"
3233
bit_field = "0.10.1"
3334
log = "0.4.14"
34-
raw-cpuid = "10.0.0"
3535
xmas-elf = "0.8.0"
36-
hashbrown = "0.11.2"
36+
hashbrown = "0.12.3"
3737
rustc-demangle = "0.1.20"
3838
intrusive-collections = "0.9.2"
3939
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
@@ -44,6 +44,12 @@ static_assertions = "1.1.0"
4444

4545
limine = { git = "https://github.com/limine-bootloader/limine-rs" }
4646

47+
cfg-if = "1.0"
48+
49+
# X86_64 specific dependencies:
50+
[target.'cfg(target_arch = "x86_64")'.dependencies]
51+
raw-cpuid = "10.0.0"
52+
4753
[dependencies.vte]
4854
git = "https://github.com/Andy-Python-Programmer/vte"
4955
features = ["no_std"]

src/aero_kernel/build.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ fn visit_dirs(dir: &Path, cb: &mut dyn FnMut(&DirEntry)) -> std::io::Result<()>
4646
}
4747

4848
fn main() -> Result<(), Box<dyn Error>> {
49+
let target = std::env::var("TARGET").expect("target triple is not set");
50+
51+
if target.contains("aarch64") {
52+
return Ok(());
53+
}
54+
4955
let mut inc_files = vec![];
5056

5157
// Assemble all of the assembly real files first as they will be included in the
@@ -79,11 +85,11 @@ fn main() -> Result<(), Box<dyn Error>> {
7985
visit_dirs(Path::new("src"), &mut |entry: &DirEntry| {
8086
let path = entry.path();
8187

88+
let object_os = path.file_name().expect("Failed to get file name");
89+
let object_file = object_os.to_str().expect("Invalid UTF-8 for file name");
90+
8291
match path.extension() {
8392
Some(ext) if ext.eq(&OsString::from("asm")) => {
84-
let object_os = path.file_name().expect("Failed to get file name");
85-
let object_file = object_os.to_str().expect("Invalid UTF-8 for file name");
86-
8793
let mut build = nasm_rs::Build::new();
8894

8995
build

src/aero_kernel/src/acpi/madt.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ use core::mem;
2222
use alloc::vec::Vec;
2323
use spin::RwLock;
2424

25-
use crate::apic::IoApicHeader;
26-
2725
use super::sdt::Sdt;
2826

2927
pub(super) const SIGNATURE: &str = "APIC";
@@ -40,10 +38,6 @@ pub struct Madt {
4038

4139
impl Madt {
4240
pub(super) fn init(&'static self) {
43-
// log::debug!("storing AP trampoline at 0x1000");
44-
45-
// let page_index = unsafe { smp_prepare_trampoline() };
46-
4741
for entry in self.iter() {
4842
match entry {
4943
MadtEntry::IoApic(e) => IO_APICS.write().push(e),
@@ -87,6 +81,15 @@ pub struct MadtIntSrcOverride {
8781
pub flags: u16,
8882
}
8983

84+
#[repr(C, packed)]
85+
pub struct IoApicHeader {
86+
pub header: EntryHeader,
87+
pub io_apic_id: u8,
88+
pub reserved: u8,
89+
pub io_apic_address: u32,
90+
pub global_system_interrupt_base: u32,
91+
}
92+
9093
enum MadtEntry {
9194
LocalApic(&'static MadtLocalApic),
9295
IoApic(&'static IoApicHeader),

0 commit comments

Comments
 (0)