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

Adding first bit of new tutorial

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