A repository for a long-term OS project titled DasOS (named after the Greek for "forest")

First part of new tutorial that finally works now

+133 -4
+1 -4
.gitignore
··· 19 19 20 20 # End of https://www.toptal.com/developers/gitignore/api/rust 21 21 22 - /limine 23 - /ovmf 24 - *.iso 25 - *.hdd 22 + runner/out_dir
+3
Cargo.toml
··· 1 + [workspace] 2 + resolver = "3" 3 + members = ["runner"]
kernel/limine.conf

This is a binary file and will not be displayed.

+5
runner/Cargo.toml
··· 1 + [package] 2 + name = "runner" 3 + version = "0.1.0" 4 + edition = "2024" 5 + publish = false
+115
runner/build.rs
··· 1 + use std::{path::{PathBuf, Path}, env, fs::{create_dir_all, remove_file}, io::{self, ErrorKind}, os::unix::fs::symlink, process::{Stdio, Command}}; 2 + 3 + fn main() { 4 + // This is the folder where a build script (this file) should place its output 5 + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); 6 + // This is the `runner` folder 7 + let runner_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); 8 + // This folder contains Limine files such as `BOOTX64.EFI` 9 + let limine_dir = PathBuf::from(env::var("LIMINE_PATH").unwrap()); 10 + 11 + // Symlink the out dir so we get a constant path to it 12 + ensure_symlink(&out_dir, runner_dir.join("out_dir")).unwrap(); 13 + 14 + // We will create an ISO file for our OS 15 + // First we create a folder which will be used to generate the ISO 16 + // We will use symlinks instead of copying to avoid unnecessary disk space used 17 + let iso_dir = out_dir.join("iso_root"); 18 + create_dir_all(&iso_dir).unwrap(); 19 + 20 + // Limine config will be in `limine.conf` 21 + let limine_conf = iso_dir.join("limine.conf"); 22 + ensure_symlink(runner_dir.join("limine.conf"), limine_conf).unwrap(); 23 + 24 + let boot_dir = iso_dir.join("boot"); 25 + create_dir_all(&boot_dir).unwrap(); 26 + 27 + // Copy files from the Limine packaeg into `boot/limine` 28 + let out_limine_dir = boot_dir.join("limine"); 29 + create_dir_all(&out_limine_dir).unwrap(); 30 + 31 + for path in [ 32 + "limine-bios.sys", 33 + "limine-bios-cd.bin", 34 + "limine-uefi-cd.bin", 35 + ] { 36 + let from = limine_dir.join(path); 37 + let to = out_limine_dir.join(path); 38 + ensure_symlink(from, to).unwrap(); 39 + } 40 + 41 + // EFI/BOOT/BOOTX64.EFI is the executable loaded by UEFI firmware 42 + // We will also copy BOOTIA32.EFI because xorisso will complain if it's not there 43 + let efi_boot_dir = iso_dir.join("EFI/BOOT"); 44 + create_dir_all(&efi_boot_dir).unwrap(); 45 + 46 + for efi_file in ["BOOTX64.EFI", "BOOTIA32.EFI"] { 47 + ensure_symlink(limine_dir.join(efi_file), efi_boot_dir.join(efi_file)).unwrap(); 48 + } 49 + 50 + // We'll call the output iso `os.iso` 51 + let output_iso = out_dir.join("os.iso"); 52 + // This command creates an ISO file from our `iso_root` folder. 53 + // Symlinks will be read (the contents will be copied into the ISO file) 54 + let status = Command::new("xorriso") 55 + .arg("-as") 56 + .arg("mkisofs") 57 + .arg("--follow-links") 58 + .arg("-b") 59 + .arg( 60 + out_limine_dir 61 + .join("limine-bios-cd.bin") 62 + .strip_prefix(&iso_dir) 63 + .unwrap(), 64 + ) 65 + .arg("-no-emul-boot") 66 + .arg("-boot-load-size") 67 + .arg("4") 68 + .arg("-boot-info-table") 69 + .arg("--efi-boot") 70 + .arg( 71 + out_limine_dir 72 + .join("limine-uefi-cd.bin") 73 + .strip_prefix(&iso_dir) 74 + .unwrap(), 75 + ) 76 + .arg("-efi-boot-part") 77 + .arg("--efi-boot-image") 78 + .arg("--protective-msdos-label") 79 + .arg(iso_dir) 80 + .arg("-o") 81 + .arg(&output_iso) 82 + .stderr(Stdio::inherit()) 83 + .stdout(Stdio::inherit()) 84 + .status() 85 + .unwrap(); 86 + 87 + assert!(status.success() || status.code().unwrap_or(-1) == 32); 88 + 89 + // This is needed to create a hybrid ISO that boots on both BIOS and UEFI. See https://github.com/limine-bootloader/limine/blob/v9.x/USAGE.md#biosuefi-hybrid-iso-creation 90 + let status = Command::new("limine") 91 + .arg("bios-install") 92 + .arg(&output_iso) 93 + .stderr(Stdio::inherit()) 94 + .stdout(Stdio::inherit()) 95 + .status() 96 + .unwrap(); 97 + 98 + assert!(status.success()); 99 + 100 + let output_iso = output_iso.display(); 101 + println!("cargo:rustc-env=ISO={output_iso}"); 102 + } 103 + 104 + pub fn ensure_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> { 105 + match remove_file(&link) { 106 + Ok(()) => Ok(()), 107 + Err(error) => match error.kind() { 108 + ErrorKind::NotFound => Ok(()), 109 + _ => Err(error), 110 + }, 111 + }?; 112 + 113 + symlink(original, link)?; 114 + Ok(()) 115 + }
+6
runner/src/main.rs
··· 1 + use std::env; 2 + 3 + fn main() { 4 + let iso = env::var("ISO").unwrap(); 5 + println!("ISO path: {iso:?}"); 6 + }
+3
rust-toolchain.toml
··· 1 + [toolchain] 2 + channel = "nightly-2025-05-31" 3 + components = ["rust-src"]