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

npx add-gitignore rust

+20 -731
+20 -4
.gitignore
··· 1 - /limine 2 - /ovmf 3 - *.iso 4 - *.hdd 1 + # Created by https://www.toptal.com/developers/gitignore/api/rust 2 + # Edit at https://www.toptal.com/developers/gitignore?templates=rust 3 + 4 + ### Rust ### 5 + # Generated by Cargo 6 + # will have compiled files and executables 7 + debug/ 8 + target/ 9 + 10 + # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 11 + # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 12 + Cargo.lock 13 + 14 + # These are backup files generated by rustfmt 15 + **/*.rs.bk 16 + 17 + # MSVC Windows builds of rustc generate these, which store debugging information 18 + *.pdb 19 + 20 + # End of https://www.toptal.com/developers/gitignore/api/rust
-251
GNUmakefile
··· 1 - # Nuke built-in rules and variables. 2 - MAKEFLAGS += -rR 3 - .SUFFIXES: 4 - 5 - # Convenience macro to reliably declare user overridable variables. 6 - override USER_VARIABLE = $(if $(filter $(origin $(1)),default undefined),$(eval override $(1) := $(2))) 7 - 8 - # Target architecture to build for. Default to x86_64. 9 - $(call USER_VARIABLE,KARCH,x86_64) 10 - 11 - # Default user QEMU flags. These are appended to the QEMU command calls. 12 - $(call USER_VARIABLE,QEMUFLAGS,-m 2G) 13 - 14 - override IMAGE_NAME := template-$(KARCH) 15 - 16 - .PHONY: all 17 - all: $(IMAGE_NAME).iso 18 - 19 - .PHONY: all-hdd 20 - all-hdd: $(IMAGE_NAME).hdd 21 - 22 - .PHONY: run 23 - run: run-$(KARCH) 24 - 25 - .PHONY: run-hdd 26 - run-hdd: run-hdd-$(KARCH) 27 - 28 - .PHONY: run-x86_64 29 - run-x86_64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso 30 - qemu-system-$(KARCH) \ 31 - -M q35 \ 32 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 33 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 34 - -cdrom $(IMAGE_NAME).iso \ 35 - $(QEMUFLAGS) 36 - 37 - .PHONY: run-hdd-x86_64 38 - run-hdd-x86_64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd 39 - qemu-system-$(KARCH) \ 40 - -M q35 \ 41 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 42 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 43 - -hda $(IMAGE_NAME).hdd \ 44 - $(QEMUFLAGS) 45 - 46 - .PHONY: run-aarch64 47 - run-aarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso 48 - qemu-system-$(KARCH) \ 49 - -M virt \ 50 - -cpu cortex-a72 \ 51 - -device ramfb \ 52 - -device qemu-xhci \ 53 - -device usb-kbd \ 54 - -device usb-mouse \ 55 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 56 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 57 - -cdrom $(IMAGE_NAME).iso \ 58 - $(QEMUFLAGS) 59 - 60 - .PHONY: run-hdd-aarch64 61 - run-hdd-aarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd 62 - qemu-system-$(KARCH) \ 63 - -M virt \ 64 - -cpu cortex-a72 \ 65 - -device ramfb \ 66 - -device qemu-xhci \ 67 - -device usb-kbd \ 68 - -device usb-mouse \ 69 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 70 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 71 - -hda $(IMAGE_NAME).hdd \ 72 - $(QEMUFLAGS) 73 - 74 - .PHONY: run-riscv64 75 - run-riscv64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso 76 - qemu-system-$(KARCH) \ 77 - -M virt \ 78 - -cpu rv64 \ 79 - -device ramfb \ 80 - -device qemu-xhci \ 81 - -device usb-kbd \ 82 - -device usb-mouse \ 83 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 84 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 85 - -cdrom $(IMAGE_NAME).iso \ 86 - $(QEMUFLAGS) 87 - 88 - .PHONY: run-hdd-riscv64 89 - run-hdd-riscv64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd 90 - qemu-system-$(KARCH) \ 91 - -M virt \ 92 - -cpu rv64 \ 93 - -device ramfb \ 94 - -device qemu-xhci \ 95 - -device usb-kbd \ 96 - -device usb-mouse \ 97 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 98 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 99 - -hda $(IMAGE_NAME).hdd \ 100 - $(QEMUFLAGS) 101 - 102 - .PHONY: run-loongarch64 103 - run-loongarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso 104 - qemu-system-$(KARCH) \ 105 - -M virt \ 106 - -cpu la464 \ 107 - -device ramfb \ 108 - -device qemu-xhci \ 109 - -device usb-kbd \ 110 - -device usb-mouse \ 111 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 112 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 113 - -cdrom $(IMAGE_NAME).iso \ 114 - $(QEMUFLAGS) 115 - 116 - .PHONY: run-hdd-loongarch64 117 - run-hdd-loongarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd 118 - qemu-system-$(KARCH) \ 119 - -M virt \ 120 - -cpu la464 \ 121 - -device ramfb \ 122 - -device qemu-xhci \ 123 - -device usb-kbd \ 124 - -device usb-mouse \ 125 - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ 126 - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd \ 127 - -hda $(IMAGE_NAME).hdd \ 128 - $(QEMUFLAGS) 129 - 130 - 131 - .PHONY: run-bios 132 - run-bios: $(IMAGE_NAME).iso 133 - qemu-system-$(KARCH) \ 134 - -M q35 \ 135 - -cdrom $(IMAGE_NAME).iso \ 136 - -boot d \ 137 - $(QEMUFLAGS) 138 - 139 - .PHONY: run-hdd-bios 140 - run-hdd-bios: $(IMAGE_NAME).hdd 141 - qemu-system-$(KARCH) \ 142 - -M q35 \ 143 - -hda $(IMAGE_NAME).hdd \ 144 - $(QEMUFLAGS) 145 - 146 - ovmf/ovmf-code-$(KARCH).fd: 147 - mkdir -p ovmf 148 - curl -Lo $@ https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/ovmf-code-$(KARCH).fd 149 - case "$(KARCH)" in \ 150 - aarch64) dd if=/dev/zero of=$@ bs=1 count=0 seek=67108864 2>/dev/null;; \ 151 - loongarch64) dd if=/dev/zero of=$@ bs=1 count=0 seek=5242880 2>/dev/null;; \ 152 - riscv64) dd if=/dev/zero of=$@ bs=1 count=0 seek=33554432 2>/dev/null;; \ 153 - esac 154 - 155 - ovmf/ovmf-vars-$(KARCH).fd: 156 - mkdir -p ovmf 157 - curl -Lo $@ https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/ovmf-vars-$(KARCH).fd 158 - case "$(KARCH)" in \ 159 - aarch64) dd if=/dev/zero of=$@ bs=1 count=0 seek=67108864 2>/dev/null;; \ 160 - loongarch64) dd if=/dev/zero of=$@ bs=1 count=0 seek=5242880 2>/dev/null;; \ 161 - riscv64) dd if=/dev/zero of=$@ bs=1 count=0 seek=33554432 2>/dev/null;; \ 162 - esac 163 - 164 - limine/limine: 165 - rm -rf limine 166 - git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 167 - $(MAKE) -C limine 168 - 169 - .PHONY: kernel 170 - kernel: 171 - $(MAKE) -C kernel 172 - 173 - $(IMAGE_NAME).iso: limine/limine kernel 174 - rm -rf iso_root 175 - mkdir -p iso_root/boot 176 - cp -v kernel/kernel iso_root/boot/ 177 - mkdir -p iso_root/boot/limine 178 - cp -v limine.conf iso_root/boot/limine/ 179 - mkdir -p iso_root/EFI/BOOT 180 - ifeq ($(KARCH),x86_64) 181 - cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ 182 - cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ 183 - cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/ 184 - xorriso -as mkisofs -b boot/limine/limine-bios-cd.bin \ 185 - -no-emul-boot -boot-load-size 4 -boot-info-table \ 186 - --efi-boot boot/limine/limine-uefi-cd.bin \ 187 - -efi-boot-part --efi-boot-image --protective-msdos-label \ 188 - iso_root -o $(IMAGE_NAME).iso 189 - ./limine/limine bios-install $(IMAGE_NAME).iso 190 - endif 191 - ifeq ($(KARCH),aarch64) 192 - cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ 193 - cp -v limine/BOOTAA64.EFI iso_root/EFI/BOOT/ 194 - xorriso -as mkisofs \ 195 - --efi-boot boot/limine/limine-uefi-cd.bin \ 196 - -efi-boot-part --efi-boot-image --protective-msdos-label \ 197 - iso_root -o $(IMAGE_NAME).iso 198 - endif 199 - ifeq ($(KARCH),riscv64) 200 - cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ 201 - cp -v limine/BOOTRISCV64.EFI iso_root/EFI/BOOT/ 202 - xorriso -as mkisofs \ 203 - --efi-boot boot/limine/limine-uefi-cd.bin \ 204 - -efi-boot-part --efi-boot-image --protective-msdos-label \ 205 - iso_root -o $(IMAGE_NAME).iso 206 - endif 207 - ifeq ($(KARCH),loongarch64) 208 - cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ 209 - cp -v limine/BOOTLOONGARCH64.EFI iso_root/EFI/BOOT/ 210 - xorriso -as mkisofs \ 211 - --efi-boot boot/limine/limine-uefi-cd.bin \ 212 - -efi-boot-part --efi-boot-image --protective-msdos-label \ 213 - iso_root -o $(IMAGE_NAME).iso 214 - endif 215 - rm -rf iso_root 216 - 217 - $(IMAGE_NAME).hdd: limine/limine kernel 218 - rm -f $(IMAGE_NAME).hdd 219 - dd if=/dev/zero bs=1M count=0 seek=64 of=$(IMAGE_NAME).hdd 220 - sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00 221 - ifeq ($(KARCH),x86_64) 222 - ./limine/limine bios-install $(IMAGE_NAME).hdd 223 - endif 224 - mformat -i $(IMAGE_NAME).hdd@@1M 225 - mmd -i $(IMAGE_NAME).hdd@@1M ::/EFI ::/EFI/BOOT ::/boot ::/boot/limine 226 - mcopy -i $(IMAGE_NAME).hdd@@1M kernel/bin-$(KARCH)/kernel ::/boot 227 - mcopy -i $(IMAGE_NAME).hdd@@1M limine.conf ::/boot/limine 228 - ifeq ($(KARCH),x86_64) 229 - mcopy -i $(IMAGE_NAME).hdd@@1M limine/limine-bios.sys ::/boot/limine 230 - mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTX64.EFI ::/EFI/BOOT 231 - mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTIA32.EFI ::/EFI/BOOT 232 - endif 233 - ifeq ($(KARCH),aarch64) 234 - mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTAA64.EFI ::/EFI/BOOT 235 - endif 236 - ifeq ($(KARCH),riscv64) 237 - mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTRISCV64.EFI ::/EFI/BOOT 238 - endif 239 - ifeq ($(KARCH),loongarch64) 240 - mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTLOONGARCH64.EFI ::/EFI/BOOT 241 - endif 242 - 243 - .PHONY: clean 244 - clean: 245 - $(MAKE) -C kernel clean 246 - rm -rf iso_root $(IMAGE_NAME).iso $(IMAGE_NAME).hdd 247 - 248 - .PHONY: distclean 249 - distclean: clean 250 - $(MAKE) -C kernel distclean 251 - rm -rf limine ovmf
-12
LICENSE
··· 1 - Copyright (C) 2023-2024 mintsuki and contributors. 2 - 3 - Permission to use, copy, modify, and/or distribute this software for any 4 - purpose with or without fee is hereby granted. 5 - 6 - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 7 - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 8 - FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 9 - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 10 - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 11 - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 12 - PERFORMANCE OF THIS SOFTWARE.
-33
README.md
··· 1 - # Limine Rust Template 2 - 3 - This repository will demonstrate how to set up a basic kernel in Rust using Limine. 4 - 5 - ## How to use this? 6 - 7 - ### Dependencies 8 - 9 - Any `make` command depends on GNU make (`gmake`) and is expected to be run using it. This usually means using `make` on most GNU/Linux distros, or `gmake` on other non-GNU systems. 10 - 11 - All `make all*` targets depend on Rust. 12 - 13 - Additionally, building an ISO with `make all` requires `xorriso`, and building a HDD/USB image with `make all-hdd` requires `sgdisk` (usually from `gdisk` or `gptfdisk` packages) and `mtools`. 14 - 15 - ### Architectural targets 16 - 17 - The `KARCH` make variable determines the target architecture to build the kernel and image for. 18 - 19 - The default `KARCH` is `x86_64`. Other options include: `aarch64`, `riscv64`, and `loongarch64`. 20 - 21 - Other architectures will need to be enabled in kernel/rust-toolchain.toml 22 - 23 - ### Makefile targets 24 - 25 - Running `make all` will compile the kernel (from the `kernel/` directory) and then generate a bootable ISO image. 26 - 27 - Running `make all-hdd` will compile the kernel and then generate a raw image suitable to be flashed onto a USB stick or hard drive/SSD. 28 - 29 - Running `make run` will build the kernel and a bootable ISO (equivalent to make all) and then run it using `qemu` (if installed). 30 - 31 - Running `make run-hdd` will build the kernel and a raw HDD image (equivalent to make all-hdd) and then run it using `qemu` (if installed). 32 - 33 - The `run-uefi` and `run-hdd-uefi` targets are equivalent to their non `-uefi` counterparts except that they boot `qemu` using a UEFI-compatible firmware.
-2
kernel/.gitignore
··· 1 - /kernel 2 - /target
-25
kernel/Cargo.lock
··· 1 - # This file is automatically @generated by Cargo. 2 - # It is not intended for manual editing. 3 - version = 4 4 - 5 - [[package]] 6 - name = "bitflags" 7 - version = "2.9.1" 8 - source = "registry+https://github.com/rust-lang/crates.io-index" 9 - checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 10 - 11 - [[package]] 12 - name = "limine" 13 - version = "0.5.0" 14 - source = "registry+https://github.com/rust-lang/crates.io-index" 15 - checksum = "af6d2ee42712e7bd2c787365cd1dab06ef59a61becbf87bec7b32b970bd2594b" 16 - dependencies = [ 17 - "bitflags", 18 - ] 19 - 20 - [[package]] 21 - name = "limine-rust-template" 22 - version = "0.1.0" 23 - dependencies = [ 24 - "limine", 25 - ]
-7
kernel/Cargo.toml
··· 1 - [package] 2 - name = "limine-rust-template" 3 - version = "0.1.0" 4 - edition = "2024" 5 - 6 - [dependencies] 7 - limine = "0.5"
-44
kernel/GNUmakefile
··· 1 - # Nuke built-in rules and variables. 2 - MAKEFLAGS += -rR 3 - .SUFFIXES: 4 - 5 - # This is the name that our final executable will have. 6 - # Change as needed. 7 - override OUTPUT := kernel 8 - 9 - # Convenience macro to reliably declare user overridable variables. 10 - override USER_VARIABLE = $(if $(filter $(origin $(1)),default undefined),$(eval override $(1) := $(2))) 11 - 12 - # Target architecture to build for. Default to x86_64. 13 - $(call USER_VARIABLE,KARCH,x86_64) 14 - 15 - ifeq ($(RUST_TARGET),) 16 - override RUST_TARGET := $(KARCH)-unknown-none 17 - ifeq ($(KARCH),riscv64) 18 - override RUST_TARGET := riscv64gc-unknown-none-elf 19 - endif 20 - endif 21 - 22 - ifeq ($(RUST_PROFILE),) 23 - override RUST_PROFILE := dev 24 - endif 25 - 26 - override RUST_PROFILE_SUBDIR := $(RUST_PROFILE) 27 - ifeq ($(RUST_PROFILE),dev) 28 - override RUST_PROFILE_SUBDIR := debug 29 - endif 30 - 31 - # Default target. 32 - .PHONY: all 33 - all: 34 - RUSTFLAGS="-C relocation-model=static" cargo build --target $(RUST_TARGET) --profile $(RUST_PROFILE) 35 - cp target/$(RUST_TARGET)/$(RUST_PROFILE_SUBDIR)/$$(cd target/$(RUST_TARGET)/$(RUST_PROFILE_SUBDIR) && find -maxdepth 1 -perm -111 -type f) kernel 36 - 37 - # Remove object files and the final executable. 38 - .PHONY: clean 39 - clean: 40 - cargo clean 41 - rm -rf kernel 42 - 43 - .PHONY: distclean 44 - distclean: clean
-7
kernel/build.rs
··· 1 - fn main() { 2 - let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); 3 - // Tell cargo to pass the linker script to the linker.. 4 - println!("cargo:rustc-link-arg=-Tlinker-{arch}.ld"); 5 - // ..and to re-run if it changes. 6 - println!("cargo:rerun-if-changed=linker-{arch}.ld"); 7 - }
-63
kernel/linker-aarch64.ld
··· 1 - /* Tell the linker that we want an aarch64 ELF64 output file */ 2 - OUTPUT_FORMAT(elf64-littleaarch64) 3 - 4 - /* We want the symbol kmain to be our entry point */ 5 - ENTRY(kmain) 6 - 7 - /* Define the program headers we want so the bootloader gives us the right */ 8 - /* MMU permissions; this also allows us to exert more control over the linking */ 9 - /* process. */ 10 - PHDRS 11 - { 12 - text PT_LOAD; 13 - rodata PT_LOAD; 14 - data PT_LOAD; 15 - } 16 - 17 - SECTIONS 18 - { 19 - /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ 20 - /* and because that is what the Limine spec mandates. */ 21 - /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ 22 - /* that is the beginning of the region. */ 23 - . = 0xffffffff80000000; 24 - 25 - .text : { 26 - *(.text .text.*) 27 - } :text 28 - 29 - /* Move to the next memory page for .rodata */ 30 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 31 - 32 - .rodata : { 33 - *(.rodata .rodata.*) 34 - } :rodata 35 - 36 - /* Move to the next memory page for .data */ 37 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 38 - 39 - .data : { 40 - *(.data .data.*) 41 - 42 - /* Place the sections that contain the Limine requests as part of the .data */ 43 - /* output section. */ 44 - KEEP(*(.requests_start_marker)) 45 - KEEP(*(.requests)) 46 - KEEP(*(.requests_end_marker)) 47 - } :data 48 - 49 - /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ 50 - /* unnecessary zeros will be written to the binary. */ 51 - /* If you need, for example, .init_array and .fini_array, those should be placed */ 52 - /* above this. */ 53 - .bss : { 54 - *(.bss .bss.*) 55 - *(COMMON) 56 - } :data 57 - 58 - /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ 59 - /DISCARD/ : { 60 - *(.eh_frame*) 61 - *(.note .note.*) 62 - } 63 - }
-63
kernel/linker-loongarch64.ld
··· 1 - /* Tell the linker that we want a loongarch64 ELF64 output file */ 2 - OUTPUT_FORMAT(elf64-loongarch) 3 - 4 - /* We want the symbol kmain to be our entry point */ 5 - ENTRY(kmain) 6 - 7 - /* Define the program headers we want so the bootloader gives us the right */ 8 - /* MMU permissions; this also allows us to exert more control over the linking */ 9 - /* process. */ 10 - PHDRS 11 - { 12 - text PT_LOAD; 13 - rodata PT_LOAD; 14 - data PT_LOAD; 15 - } 16 - 17 - SECTIONS 18 - { 19 - /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ 20 - /* and because that is what the Limine spec mandates. */ 21 - /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ 22 - /* that is the beginning of the region. */ 23 - . = 0xffffffff80000000; 24 - 25 - .text : { 26 - *(.text .text.*) 27 - } :text 28 - 29 - /* Move to the next memory page for .rodata */ 30 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 31 - 32 - .rodata : { 33 - *(.rodata .rodata.*) 34 - } :rodata 35 - 36 - /* Move to the next memory page for .data */ 37 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 38 - 39 - .data : { 40 - *(.data .data.*) 41 - 42 - /* Place the sections that contain the Limine requests as part of the .data */ 43 - /* output section. */ 44 - KEEP(*(.requests_start_marker)) 45 - KEEP(*(.requests)) 46 - KEEP(*(.requests_end_marker)) 47 - } :data 48 - 49 - /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ 50 - /* unnecessary zeros will be written to the binary. */ 51 - /* If you need, for example, .init_array and .fini_array, those should be placed */ 52 - /* above this. */ 53 - .bss : { 54 - *(.bss .bss.*) 55 - *(COMMON) 56 - } :data 57 - 58 - /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ 59 - /DISCARD/ : { 60 - *(.eh_frame*) 61 - *(.note .note.*) 62 - } 63 - }
-66
kernel/linker-riscv64.ld
··· 1 - /* Tell the linker that we want a riscv64 ELF64 output file */ 2 - OUTPUT_FORMAT(elf64-littleriscv) 3 - 4 - /* We want the symbol kmain to be our entry point */ 5 - ENTRY(kmain) 6 - 7 - /* Define the program headers we want so the bootloader gives us the right */ 8 - /* MMU permissions; this also allows us to exert more control over the linking */ 9 - /* process. */ 10 - PHDRS 11 - { 12 - text PT_LOAD; 13 - rodata PT_LOAD; 14 - data PT_LOAD; 15 - } 16 - 17 - SECTIONS 18 - { 19 - /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ 20 - /* and because that is what the Limine spec mandates. */ 21 - /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ 22 - /* that is the beginning of the region. */ 23 - . = 0xffffffff80000000; 24 - 25 - .text : { 26 - *(.text .text.*) 27 - } :text 28 - 29 - /* Move to the next memory page for .rodata */ 30 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 31 - 32 - .rodata : { 33 - *(.rodata .rodata.*) 34 - } :rodata 35 - 36 - /* Move to the next memory page for .data */ 37 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 38 - 39 - .data : { 40 - *(.data .data.*) 41 - 42 - /* Place the sections that contain the Limine requests as part of the .data */ 43 - /* output section. */ 44 - KEEP(*(.requests_start_marker)) 45 - KEEP(*(.requests)) 46 - KEEP(*(.requests_end_marker)) 47 - 48 - *(.sdata .sdata.*) 49 - } :data 50 - 51 - /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ 52 - /* unnecessary zeros will be written to the binary. */ 53 - /* If you need, for example, .init_array and .fini_array, those should be placed */ 54 - /* above this. */ 55 - .bss : { 56 - *(.sbss .sbss.*) 57 - *(.bss .bss.*) 58 - *(COMMON) 59 - } :data 60 - 61 - /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ 62 - /DISCARD/ : { 63 - *(.eh_frame*) 64 - *(.note .note.*) 65 - } 66 - }
-63
kernel/linker-x86_64.ld
··· 1 - /* Tell the linker that we want an x86_64 ELF64 output file */ 2 - OUTPUT_FORMAT(elf64-x86-64) 3 - 4 - /* We want the symbol kmain to be our entry point */ 5 - ENTRY(kmain) 6 - 7 - /* Define the program headers we want so the bootloader gives us the right */ 8 - /* MMU permissions; this also allows us to exert more control over the linking */ 9 - /* process. */ 10 - PHDRS 11 - { 12 - text PT_LOAD; 13 - rodata PT_LOAD; 14 - data PT_LOAD; 15 - } 16 - 17 - SECTIONS 18 - { 19 - /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ 20 - /* and because that is what the Limine spec mandates. */ 21 - /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ 22 - /* that is the beginning of the region. */ 23 - . = 0xffffffff80000000; 24 - 25 - .text : { 26 - *(.text .text.*) 27 - } :text 28 - 29 - /* Move to the next memory page for .rodata */ 30 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 31 - 32 - .rodata : { 33 - *(.rodata .rodata.*) 34 - } :rodata 35 - 36 - /* Move to the next memory page for .data */ 37 - . = ALIGN(CONSTANT(MAXPAGESIZE)); 38 - 39 - .data : { 40 - *(.data .data.*) 41 - 42 - /* Place the sections that contain the Limine requests as part of the .data */ 43 - /* output section. */ 44 - KEEP(*(.requests_start_marker)) 45 - KEEP(*(.requests)) 46 - KEEP(*(.requests_end_marker)) 47 - } :data 48 - 49 - /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ 50 - /* unnecessary zeros will be written to the binary. */ 51 - /* If you need, for example, .init_array and .fini_array, those should be placed */ 52 - /* above this. */ 53 - .bss : { 54 - *(.bss .bss.*) 55 - *(COMMON) 56 - } :data 57 - 58 - /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ 59 - /DISCARD/ : { 60 - *(.eh_frame*) 61 - *(.note .note.*) 62 - } 63 - }
-8
kernel/rust-toolchain.toml
··· 1 - [toolchain] 2 - channel = "nightly" 3 - targets = [ 4 - "x86_64-unknown-none", 5 - # "aarch64-unknown-none", 6 - # "riscv64gc-unknown-none-elf", 7 - # "loongarch64-unknown-none", 8 - ]
-73
kernel/src/main.rs
··· 1 - #![no_std] 2 - #![no_main] 3 - 4 - use core::arch::asm; 5 - 6 - use limine::BaseRevision; 7 - use limine::request::{FramebufferRequest, RequestsEndMarker, RequestsStartMarker}; 8 - 9 - /// Sets the base revision to the latest revision supported by the crate. 10 - /// See specification for further info. 11 - /// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler. 12 - #[used] 13 - // The .requests section allows limine to find the requests faster and more safely. 14 - #[unsafe(link_section = ".requests")] 15 - static BASE_REVISION: BaseRevision = BaseRevision::new(); 16 - 17 - #[used] 18 - #[unsafe(link_section = ".requests")] 19 - static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new(); 20 - 21 - /// Define the stand and end markers for Limine requests. 22 - #[used] 23 - #[unsafe(link_section = ".requests_start_marker")] 24 - static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new(); 25 - #[used] 26 - #[unsafe(link_section = ".requests_end_marker")] 27 - static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new(); 28 - 29 - #[unsafe(no_mangle)] 30 - unsafe extern "C" fn kmain() -> ! { 31 - // All limine requests must also be referenced in a called function, otherwise they may be 32 - // removed by the linker. 33 - assert!(BASE_REVISION.is_supported()); 34 - 35 - if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() { 36 - if let Some(framebuffer) = framebuffer_response.framebuffers().next() { 37 - for i in 0..100_u64 { 38 - // Calculate the pixel offset using the framebuffer information we obtained above. 39 - // We skip `i` scanlines (pitch is provided in bytes) and add `i * 4` to skip `i` pixels forward. 40 - let pixel_offset = i * framebuffer.pitch() + i * 4; 41 - 42 - // Write 0xFFFFFFFF to the provided pixel offset to fill it white. 43 - unsafe { 44 - framebuffer 45 - .addr() 46 - .add(pixel_offset as usize) 47 - .cast::<u32>() 48 - .write(0xFFFFFFFF) 49 - }; 50 - } 51 - } 52 - } 53 - 54 - hcf(); 55 - } 56 - 57 - #[panic_handler] 58 - fn rust_panic(_info: &core::panic::PanicInfo) -> ! { 59 - hcf(); 60 - } 61 - 62 - fn hcf() -> ! { 63 - loop { 64 - unsafe { 65 - #[cfg(target_arch = "x86_64")] 66 - asm!("hlt"); 67 - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] 68 - asm!("wfi"); 69 - #[cfg(target_arch = "loongarch64")] 70 - asm!("idle 0"); 71 - } 72 - } 73 - }
-10
limine.conf
··· 1 - # Timeout in seconds that Limine will use before automatically booting. 2 - timeout: 3 3 - 4 - # The entry name that will be displayed in the boot menu. 5 - /Limine Template 6 - # We use the Limine boot protocol. 7 - protocol: limine 8 - 9 - # Path to the kernel to boot. boot():/ represents the partition on which limine.conf is located. 10 - kernel_path: boot():/boot/kernel