From d35463e1959cb64828c3166527b06e4a79cbea5e Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 6 Mar 2026 16:53:18 +0100 Subject: reorganise --- .cargo/config.toml | 5 - CHANGELOG.md | 7 - Cargo.lock | 359 --------------------------------------------- Cargo.toml | 17 --- README.md | 48 +----- asm/boot.asm | 286 ------------------------------------ asm/kernel.asm | 23 --- bootle/.cargo/config.toml | 5 + bootle/CHANGELOG.md | 7 + bootle/Cargo.lock | 359 +++++++++++++++++++++++++++++++++++++++++++++ bootle/Cargo.toml | 17 +++ bootle/README.md | 28 ++++ bootle/package.nix | 68 +++++++++ bootle/rust-toolchain.toml | 5 + bootle/src/lib.rs | 55 +++++++ bootle/src/linker.ld | 8 + bootler/CHANGELOG.md | 7 + bootler/README.md | 43 ++++++ bootler/asm/boot.asm | 286 ++++++++++++++++++++++++++++++++++++ bootler/asm/kernel.asm | 23 +++ bootler/package.nix | 49 +++++++ flake.nix | 7 +- nix/package.nix | 47 ------ nix/pkgs/bootle.nix | 68 --------- nix/pkgs/bootler.nix | 49 ------- rust-toolchain.toml | 5 - src/lib.rs | 55 ------- src/linker.ld | 8 - 28 files changed, 969 insertions(+), 975 deletions(-) delete mode 100644 .cargo/config.toml delete mode 100644 CHANGELOG.md delete mode 100644 Cargo.lock delete mode 100644 Cargo.toml delete mode 100644 asm/boot.asm delete mode 100644 asm/kernel.asm create mode 100644 bootle/.cargo/config.toml create mode 100644 bootle/CHANGELOG.md create mode 100644 bootle/Cargo.lock create mode 100644 bootle/Cargo.toml create mode 100644 bootle/README.md create mode 100644 bootle/package.nix create mode 100644 bootle/rust-toolchain.toml create mode 100644 bootle/src/lib.rs create mode 100644 bootle/src/linker.ld create mode 100644 bootler/CHANGELOG.md create mode 100644 bootler/README.md create mode 100644 bootler/asm/boot.asm create mode 100644 bootler/asm/kernel.asm create mode 100644 bootler/package.nix delete mode 100644 nix/package.nix delete mode 100644 nix/pkgs/bootle.nix delete mode 100644 nix/pkgs/bootler.nix delete mode 100644 rust-toolchain.toml delete mode 100644 src/lib.rs delete mode 100644 src/linker.ld diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 74cdc7b..0000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "x86_64-unknown-none" -rustflags = [ - "-Crelocation-model=static" -] diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 53c30a7..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# Changelog - -## [0.1.0] - 2026-03-05 - -### Added - -- CHANGELOG.md diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index f69efc7..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,359 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9acbfca36652500c911ddb767ed433e3ed99b032b5d935be73c6923662db1d43" -dependencies = [ - "cpp_demangle", - "fallible-iterator", - "gimli", - "memmap2", - "object", - "rustc-demangle", - "smallvec", - "typed-arena", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "bootle" -version = "0.1.0" -dependencies = [ - "addr2line", - "cfg-if", - "dlmalloc", - "fortanix-sgx-abi", - "getopts", - "hashbrown", - "hermit-abi", - "object", - "r-efi", - "r-efi-alloc", - "rustc-demangle", - "rustc-literal-escaper", - "unwinding", - "wasi", -] - -[[package]] -name = "cfg-if" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" - -[[package]] -name = "cpp_demangle" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "dlmalloc" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3a2dbee57b69fbb5dbe852fa9c0925697fb0c7fbcb1593e90e5ffaedf13d51" -dependencies = [ - "cfg-if", - "libc", - "windows-sys", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "flate2" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "fortanix-sgx-abi" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efc85edd5b83e8394f4371dd0da6859dff63dd387dab8568fece6af4cde6f84" - -[[package]] -name = "getopts" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" -dependencies = [ - "fallible-iterator", - "stable_deref_trait", -] - -[[package]] -name = "hashbrown" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "libc" -version = "0.2.182" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "memmap2" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" -dependencies = [ - "libc", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "object" -version = "0.37.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a" -dependencies = [ - "flate2", - "memchr", - "ruzstd", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "r-efi-alloc" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2f58ef3ca9bb0f9c44d9aa8537601bcd3df94cc9314a40178cadf7d4466354" -dependencies = [ - "r-efi", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" - -[[package]] -name = "rustc-literal-escaper" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ee29da77c5a54f42697493cd4c9b9f31b74df666a6c04dfc4fde77abe0438b" - -[[package]] -name = "ruzstd" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" -dependencies = [ - "twox-hash", -] - -[[package]] -name = "simd-adler32" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "twox-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" - -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "unwinding" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d80f6c2bfede213d9a90b4a14f3eb99b84e33c52df6c1a15de0a100f5a88751" -dependencies = [ - "gimli", - "libc", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index c4d5b40..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "bootle" -version = "0.1.0" -edition = "2024" - -[lib] -crate-type = ["staticlib"] - -[dependencies] - -[profile.release] -panic = "abort" -opt-level = 'z' -debug = false - -[profile.dev] -panic = "abort" diff --git a/README.md b/README.md index e206ab9..3a9246b 100644 --- a/README.md +++ b/README.md @@ -2,53 +2,15 @@ Call me Terry Davis because... actually please don't. I have visions: aspiration # bootle -hobby kernel written in rust. It's just for playing around... for now :p +hobby kernel -run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootle` +status: basically nothing, come back later # bootler -hobby bootloader written in asm. It's just for playing around... for now :p - -run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootler` - -### memory map - -``` -+------ 0x00100000 ------+ -| hardware, bios stuff | -+------ 0x00080000 ------+ -| | -| | -+------ 0x00010200 ------+ -| x86_64 kernel | -+------ 0x00010000 ------+ -| | -| | -+------ 0x00009000 ------+ -| IDT | -+------ 0x00008000 ------+ -| | -| | -+------ 0x00007E00 ------+ -| bootloader (boot.asm) | -+------ 0x00007C00 ------+ -| stack | TODO get real stack -+------ 0x00005000 ------+ -| PT | -+------ 0x00004000 ------+ -| PDT | -+------ 0x00003000 ------+ -| PDPT | -+------ 0x00002000 ------+ -| PML4T | -+------ 0x00001000 ------+ -| | -| | -+------ 0x00000500 ------+ -| bios stuff | -+------ 0x00000000 ------+ -``` +hobby 1-stage legacy mode bootloader + +status: gets to long mode, loads+jumps to kernel, starts idt and gdt... :) --- diff --git a/asm/boot.asm b/asm/boot.asm deleted file mode 100644 index 5291d58..0000000 --- a/asm/boot.asm +++ /dev/null @@ -1,286 +0,0 @@ -; bootler -; legacy bootloader in nasm-flavoured asm -; 2026 Andromeda -; GPL licensed - -LOAD_ADDR equ 0x7C00 - -KERNEL_START equ 2 ; first sector on disk to load kernel from; 1 indexed -KERNEL_SIZE equ 1 ; length of kernel in sectors -KERNEL_LOAD_ADDR_ES equ 0x1000 ; kernel to be loaded at es * 0x10 + 0x0000 - -PAGE_TABLE_LOAD_ADDR equ 0x1000 ; start of page table; 4 * pt size -PAGE_TABLE_SIZE equ 0x1000 ; size of page table in bytes - -; 64 bit IDT stuff -IDT_ADDR equ 0x8000 ; bottom of IDT -IDT_SIZE equ 0x1000 ; size of IDT - -IDT_SEGMENT equ 0x0008 ; gdt code segment to jump to for idt calls - -; magic numbers and things -A20_LINE_ENABLE equ 0x2401 ; magic number in ax to enable a20 line with 0x15 -BIOS_INT_DISK_OP equ 0x13 -BIOS_INT_MEMORY_OP equ 0x15 - -CR0_PE equ 1 << 0 ; Protected Mode Enabled -CR0_PG equ 1 << 31 ; Paging - -CR4_PAE equ 1 << 5 ; Physical Address Extension -CR4_PGE equ 1 << 7 ; Page Global Enabled - -MSR_IA32_EFER equ 0xC0000080 ; Extended Feature Enable model-specific Register - -[bits 16] -[org LOAD_ADDR] - -jmp 0x0000:.cs_reset ; in case it loads us at 0x7C00:0x0000 -.cs_reset: - -xor ax, ax -mov ss, ax -mov sp, LOAD_ADDR ; stack builds down, loader faces up -mov ds, ax -mov es, ax -mov fs, ax -mov gs, ax -cld - -; activate a20 -mov ax, A20_LINE_ENABLE -int BIOS_INT_MEMORY_OP -jc error -mov si, msg_a20_line -call print - -; prep to read disk -mov al, KERNEL_SIZE ; size in sectors, min. 1 -mov ch, 0 ; cylinder -mov cl, KERNEL_START ; start sector, 1-indexed -mov dh, 0 ; head -; dl set by bios -mov bx, KERNEL_LOAD_ADDR_ES ; load addr es:bx -mov es, bx -xor bx, bx - -; read disk -mov ah, 0x02 -int BIOS_INT_DISK_OP -jc error -mov si, msg_disk_read -call print - -; zero es -push ax -xor ax, ax -mov es, ax -pop ax - -mov edi, PAGE_TABLE_LOAD_ADDR -jmp lm_load - -; expects: -; es:edi -> 16kb for page table -; ss:esp -> stack -; heavily based on https://wiki.osdev.org/Entering_Long_Mode_Directly -lm_load: - ; clear page table - push di - mov ecx, PAGE_TABLE_SIZE - xor eax, eax - cld - rep stosd ; clear space for all 4 tables - pop di - - ; PML4TE0 - lea eax, [es:di + PAGE_TABLE_SIZE] - or eax, 11b - mov [es:di], eax - - ; PDPT0E0 - lea eax, [es:di + 2 * PAGE_TABLE_SIZE] - or eax, 11b - mov [es:di + PAGE_TABLE_SIZE], eax - - ; PDT0E0 - lea eax, [es:di + 3 * PAGE_TABLE_SIZE] - or eax, 11b - mov [es:di + 2 * PAGE_TABLE_SIZE], eax - - ; PT0 - push di - lea di, [di + 3 * PAGE_TABLE_SIZE] - mov eax, 0x11 - - .set_pt_entry - mov [es:di], eax - add eax, 0x1000 - add di, 8 - cmp eax, 0x200000 ; size of page - jb .set_pt_entry - - pop di - - ; disable interrupts from PIC by masking all interrupts - mov al, 0xFF ; mask - out 0xA1, al - out 0x21, al - - ; PAE, PGE - mov eax, CR4_PAE | CR4_PGE - mov cr4, eax - - ; cr3 -> PML4TE0 - mov edx, edi - mov cr3, edx - - ; highs LME bit in EFER - mov ecx, MSR_IA32_EFER - rdmsr - or eax, 0x00000100 - wrmsr - - ; activate long mode - mov ebx, cr0 - or ebx, CR0_PG | CR0_PE - mov cr0, ebx - - cli - lgdt [gdt_descriptor] - - jmp 0x08:lm_start - -error: - mov si, .msg - call print - .msg db "err ", 0x00 - ret - -done: - hlt - jmp done - -print: - pushad - .loop - lodsb - test al, al - je .done - mov ah, 0x0E - int 0x10 - jmp .loop - .done - popad - ret - -; TODO make readable (yoinked from https://wiki.osdev.org/Entering_Long_Mode_Directly) -gdt_data: - dq 0x0000000000000000 - dq 0x00209A0000000000 - dq 0x0000920000000000 - -gdt_descriptor: - dw $ - gdt_data - 1 ; size - dd gdt_data ; start - -[bits 64] - -; long mode entry -lm_start: - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - ; set up serial device - ; TODO poll and whatnot (in rust??) - mov dx, 0x3F8 - - ; qemu -no-graphic overlaps serial and bios output without this - mov al, 0x0D - out dx, al - mov al, 0x0A - out dx, al - - ; initialize IDT at IDT_ADDR - call idt_init - - int3 ; silly test - - jmp KERNEL_LOAD_ADDR_ES * 0x10 - -idt_init: - ; clear space for idt - mov rdi, IDT_ADDR - push di - mov rcx, IDT_SIZE / 4 - xor rax, rax - cld - rep stosd ; clear double word for each rcx - pop di - - push rdx ; dx contains the output device - ; nothing between here and the `pop rdx` will be able to print - - ; breakpoint - mov rdi, 0x8E ; present, no dpl, interrupt - mov rsi, 0x03 ; breakpoint interrupt - lea rdx, [int_hdl_dummy] - call mk_idt_entry - - pop rdx ; get back dx output device - - lidt [idt_descriptor] - - ret - -int_hdl_dummy: - mov rsi, .msg - call lm_print - iretq - .msg db "INTdummy", 0x0D, 0x0A, 0x00 - -; rdi = flags -; rsi = entry number -; rdx -> handler -mk_idt_entry: - mov rax, rdx - mov rcx, rsi - - shl rcx, 4 ; offset = entry number * 16 - add rcx, IDT_ADDR - - mov word [rcx + 0], ax ; offset - mov word [rcx + 2], IDT_SEGMENT ; code segment - mov word [rcx + 5], di - mov byte [rcx + 4], 0 ; IST (0 = none) - shr rax, 16 - mov word [rcx + 6], ax ; offset - shr rax, 16 - mov dword [rcx + 8], eax ; offset - mov dword [rcx + 12], 0 ; reserved - ret - -lm_print: - .loop - mov al, [rsi] - test al, al - jz .done - out dx, al - inc si - jmp .loop - .done: - ret - -idt_descriptor: - dw IDT_SIZE - 1 ; size - dq IDT_ADDR ; start - -msg_a20_line db "a20 line", 0x0D, 0x0A, 0x00 -msg_disk_read db "disk", 0x0D, 0x0A, 0x00 - -times 510-($-$$) db 0 ; 2 bytes less now -db 0x55 -db 0xAA diff --git a/asm/kernel.asm b/asm/kernel.asm deleted file mode 100644 index b4cbb30..0000000 --- a/asm/kernel.asm +++ /dev/null @@ -1,23 +0,0 @@ -[bits 64] - -mov al, 'K' -out dx, al -mov al, 'e' -out dx, al -mov al, 'r' -out dx, al -mov al, 'n' -out dx, al -mov al, 'e' -out dx, al -mov al, 'l' -out dx, al -mov al, 0x0D -out dx, al -mov al, 0x0A -out dx, al -mov al, 0x00 -out dx, al -.done - hlt - jmp .done diff --git a/bootle/.cargo/config.toml b/bootle/.cargo/config.toml new file mode 100644 index 0000000..74cdc7b --- /dev/null +++ b/bootle/.cargo/config.toml @@ -0,0 +1,5 @@ +[build] +target = "x86_64-unknown-none" +rustflags = [ + "-Crelocation-model=static" +] diff --git a/bootle/CHANGELOG.md b/bootle/CHANGELOG.md new file mode 100644 index 0000000..53c30a7 --- /dev/null +++ b/bootle/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +## [0.1.0] - 2026-03-05 + +### Added + +- CHANGELOG.md diff --git a/bootle/Cargo.lock b/bootle/Cargo.lock new file mode 100644 index 0000000..f69efc7 --- /dev/null +++ b/bootle/Cargo.lock @@ -0,0 +1,359 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9acbfca36652500c911ddb767ed433e3ed99b032b5d935be73c6923662db1d43" +dependencies = [ + "cpp_demangle", + "fallible-iterator", + "gimli", + "memmap2", + "object", + "rustc-demangle", + "smallvec", + "typed-arena", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "bootle" +version = "0.1.0" +dependencies = [ + "addr2line", + "cfg-if", + "dlmalloc", + "fortanix-sgx-abi", + "getopts", + "hashbrown", + "hermit-abi", + "object", + "r-efi", + "r-efi-alloc", + "rustc-demangle", + "rustc-literal-escaper", + "unwinding", + "wasi", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "cpp_demangle" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "dlmalloc" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3a2dbee57b69fbb5dbe852fa9c0925697fb0c7fbcb1593e90e5ffaedf13d51" +dependencies = [ + "cfg-if", + "libc", + "windows-sys", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "fortanix-sgx-abi" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efc85edd5b83e8394f4371dd0da6859dff63dd387dab8568fece6af4cde6f84" + +[[package]] +name = "getopts" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +dependencies = [ + "fallible-iterator", + "stable_deref_trait", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "libc" +version = "0.2.182" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "memmap2" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +dependencies = [ + "libc", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "object" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a" +dependencies = [ + "flate2", + "memchr", + "ruzstd", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi-alloc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2f58ef3ca9bb0f9c44d9aa8537601bcd3df94cc9314a40178cadf7d4466354" +dependencies = [ + "r-efi", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" + +[[package]] +name = "rustc-literal-escaper" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ee29da77c5a54f42697493cd4c9b9f31b74df666a6c04dfc4fde77abe0438b" + +[[package]] +name = "ruzstd" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unwinding" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d80f6c2bfede213d9a90b4a14f3eb99b84e33c52df6c1a15de0a100f5a88751" +dependencies = [ + "gimli", + "libc", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/bootle/Cargo.toml b/bootle/Cargo.toml new file mode 100644 index 0000000..c4d5b40 --- /dev/null +++ b/bootle/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "bootle" +version = "0.1.0" +edition = "2024" + +[lib] +crate-type = ["staticlib"] + +[dependencies] + +[profile.release] +panic = "abort" +opt-level = 'z' +debug = false + +[profile.dev] +panic = "abort" diff --git a/bootle/README.md b/bootle/README.md new file mode 100644 index 0000000..da47027 --- /dev/null +++ b/bootle/README.md @@ -0,0 +1,28 @@ +# bootle + +hobby kernel written in rust. It's just for playing around... for now :p + +run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootle` + +### memory map + +``` ++------ 0x00100000 ------+ +| hardware, bios stuff | ++------ 0x00080000 ------+ +| | +| | ++------ 0x00010200 ------+ +| kernel | ++------ 0x00010000 ------+ +| bootloader stuff | +| includes stack, gdt, | +| idt for the time being | ++------ 0x00000500 ------+ +| bios stuff | ++------ 0x00000000 ------+ +``` + +--- + +this project follows [Common Changelog](https://common-changelog.org) guidelines diff --git a/bootle/package.nix b/bootle/package.nix new file mode 100644 index 0000000..a5de5eb --- /dev/null +++ b/bootle/package.nix @@ -0,0 +1,68 @@ +{ + callPackage, + rust-bin, + naersk, + bootler, + qemu, + ... +}: let + rust-toolchain = rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + naersk' = callPackage naersk { + cargo = rust-toolchain; + rustc = rust-toolchain; + clippy = rust-toolchain; + }; +in (naersk'.buildPackage { + src = ./.; + + # deps for rust-src + additionalCargoLock = "${rust-toolchain.availableComponents.rust-src}/lib/rustlib/src/rust/library/Cargo.lock"; + + # just library build + copyBins = false; + copyLibs = true; + release = true; + + # build std + cargoBuildOptions = x: + x + ++ [ + "-Zbuild-std" + ]; + + postInstall = '' + ld --oformat binary \ + -o kernel.bin \ + -T src/linker.ld \ + -e _start \ + target/x86_64-unknown-none/release/libbootle.a + + dd if=/dev/zero of=disk bs=512 count=2 + dd if=${bootler}/bin/boot.bin of=disk conv=notrunc + dd if=kernel.bin of=disk bs=512 seek=1 conv=notrunc + + mkdir -p $out/lib + mkdir -p $out/bin + + cat<$out/bin/bootle + #!/usr/bin/env bash + + mkdir -p ./.bootle + cp $(echo $out)/bin/disk ./.bootle/disk + chmod a+w ./.bootle/disk + + ${qemu}/bin/qemu-system-x86_64 \ + -nographic \ + -drive file=./.bootle/disk,format=raw,index=0,media=disk + + rm ./.bootle -r + + EOF + + chmod +x $out/bin/bootle + + cp target/x86_64-unknown-none/release/libbootle.a $out/lib + cp kernel.bin $out/bin + cp disk $out/bin + ''; +}) diff --git a/bootle/rust-toolchain.toml b/bootle/rust-toolchain.toml new file mode 100644 index 0000000..22068c5 --- /dev/null +++ b/bootle/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "nightly" +components = ["rust-src"] +targets = ["x86_64-unknown-none"] +profile = "default" diff --git a/bootle/src/lib.rs b/bootle/src/lib.rs new file mode 100644 index 0000000..adc1aab --- /dev/null +++ b/bootle/src/lib.rs @@ -0,0 +1,55 @@ +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[unsafe(no_mangle)] +pub extern "C" fn _start() -> ! { + welcome_serial(); + halt() +} + +fn print_serial(s: &str) { + let mut bytes = s.bytes(); + while let Some(b) = bytes.next() { + unsafe { + core::arch::asm!( + "out dx, al" + , in("al") b + ) + }; + } +} + +fn println_serial(s: &str) { + print_serial(s); + print_serial("\n"); +} + +fn welcome_serial() { + print_serial(ANSI_PINK); + println_serial("\nWelcome to Bootle OS"); + println_serial("All code GPL licensed and freely available on git.mtgmonkey.net"); + print_serial("Enjoy your time! Press "); + print_serial(ANSI_RED); + print_serial("ctrl+a x"); + print_serial(ANSI_PINK); + println_serial(" to escape Qemu"); + print_serial(ANSI_CLEAR); +} + +#[panic_handler] +fn panic(_: &PanicInfo) -> ! { + print_serial("panicked"); + halt() +} + +fn halt() -> ! { + unsafe { core::arch::asm!("hlt") }; + halt() +} + +const ANSI_CLEAR: &str = "\x1b[0m"; +const ANSI_RED: &str = "\x1b[31m"; +const ANSI_PINK: &str = "\x1b[35m"; +const ANSI_GREEN: &str = "\x1b[32m"; diff --git a/bootle/src/linker.ld b/bootle/src/linker.ld new file mode 100644 index 0000000..b523bc5 --- /dev/null +++ b/bootle/src/linker.ld @@ -0,0 +1,8 @@ +SECTIONS +{ + . = 0x00010000; + .text : { + *(.text._start) + *(.text*) + } +} diff --git a/bootler/CHANGELOG.md b/bootler/CHANGELOG.md new file mode 100644 index 0000000..eff4a62 --- /dev/null +++ b/bootler/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +## [0.1.0] - 2026-03-06 + +### Added + +- initialised CHANGELOG.md diff --git a/bootler/README.md b/bootler/README.md new file mode 100644 index 0000000..bf50ce2 --- /dev/null +++ b/bootler/README.md @@ -0,0 +1,43 @@ +# bootler + +hobby bootloader, 1-stage, legacy mode :p + +run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootler` + +### memory map + +``` +. . +: : +| longmode kernel | ++------ 0x00010000 ------+ +| | +| | ++------ 0x00009000 ------+ +| IDT | ++------ 0x00008000 ------+ +| | +| | ++------ 0x00007E00 ------+ +| bootloader (boot.asm) | ++------ 0x00007C00 ------+ +| stack | ++------ 0x00005000 ------+ +| PT | ++------ 0x00004000 ------+ +| PDT | ++------ 0x00003000 ------+ +| PDPT | ++------ 0x00002000 ------+ +| PML4T | ++------ 0x00001000 ------+ +| | +| | ++------ 0x00000500 ------+ +| bios stuff | ++------ 0x00000000 ------+ +``` + +--- + +this project follows [Common Changelog](https://common-changelog.org) guidelines diff --git a/bootler/asm/boot.asm b/bootler/asm/boot.asm new file mode 100644 index 0000000..5291d58 --- /dev/null +++ b/bootler/asm/boot.asm @@ -0,0 +1,286 @@ +; bootler +; legacy bootloader in nasm-flavoured asm +; 2026 Andromeda +; GPL licensed + +LOAD_ADDR equ 0x7C00 + +KERNEL_START equ 2 ; first sector on disk to load kernel from; 1 indexed +KERNEL_SIZE equ 1 ; length of kernel in sectors +KERNEL_LOAD_ADDR_ES equ 0x1000 ; kernel to be loaded at es * 0x10 + 0x0000 + +PAGE_TABLE_LOAD_ADDR equ 0x1000 ; start of page table; 4 * pt size +PAGE_TABLE_SIZE equ 0x1000 ; size of page table in bytes + +; 64 bit IDT stuff +IDT_ADDR equ 0x8000 ; bottom of IDT +IDT_SIZE equ 0x1000 ; size of IDT + +IDT_SEGMENT equ 0x0008 ; gdt code segment to jump to for idt calls + +; magic numbers and things +A20_LINE_ENABLE equ 0x2401 ; magic number in ax to enable a20 line with 0x15 +BIOS_INT_DISK_OP equ 0x13 +BIOS_INT_MEMORY_OP equ 0x15 + +CR0_PE equ 1 << 0 ; Protected Mode Enabled +CR0_PG equ 1 << 31 ; Paging + +CR4_PAE equ 1 << 5 ; Physical Address Extension +CR4_PGE equ 1 << 7 ; Page Global Enabled + +MSR_IA32_EFER equ 0xC0000080 ; Extended Feature Enable model-specific Register + +[bits 16] +[org LOAD_ADDR] + +jmp 0x0000:.cs_reset ; in case it loads us at 0x7C00:0x0000 +.cs_reset: + +xor ax, ax +mov ss, ax +mov sp, LOAD_ADDR ; stack builds down, loader faces up +mov ds, ax +mov es, ax +mov fs, ax +mov gs, ax +cld + +; activate a20 +mov ax, A20_LINE_ENABLE +int BIOS_INT_MEMORY_OP +jc error +mov si, msg_a20_line +call print + +; prep to read disk +mov al, KERNEL_SIZE ; size in sectors, min. 1 +mov ch, 0 ; cylinder +mov cl, KERNEL_START ; start sector, 1-indexed +mov dh, 0 ; head +; dl set by bios +mov bx, KERNEL_LOAD_ADDR_ES ; load addr es:bx +mov es, bx +xor bx, bx + +; read disk +mov ah, 0x02 +int BIOS_INT_DISK_OP +jc error +mov si, msg_disk_read +call print + +; zero es +push ax +xor ax, ax +mov es, ax +pop ax + +mov edi, PAGE_TABLE_LOAD_ADDR +jmp lm_load + +; expects: +; es:edi -> 16kb for page table +; ss:esp -> stack +; heavily based on https://wiki.osdev.org/Entering_Long_Mode_Directly +lm_load: + ; clear page table + push di + mov ecx, PAGE_TABLE_SIZE + xor eax, eax + cld + rep stosd ; clear space for all 4 tables + pop di + + ; PML4TE0 + lea eax, [es:di + PAGE_TABLE_SIZE] + or eax, 11b + mov [es:di], eax + + ; PDPT0E0 + lea eax, [es:di + 2 * PAGE_TABLE_SIZE] + or eax, 11b + mov [es:di + PAGE_TABLE_SIZE], eax + + ; PDT0E0 + lea eax, [es:di + 3 * PAGE_TABLE_SIZE] + or eax, 11b + mov [es:di + 2 * PAGE_TABLE_SIZE], eax + + ; PT0 + push di + lea di, [di + 3 * PAGE_TABLE_SIZE] + mov eax, 0x11 + + .set_pt_entry + mov [es:di], eax + add eax, 0x1000 + add di, 8 + cmp eax, 0x200000 ; size of page + jb .set_pt_entry + + pop di + + ; disable interrupts from PIC by masking all interrupts + mov al, 0xFF ; mask + out 0xA1, al + out 0x21, al + + ; PAE, PGE + mov eax, CR4_PAE | CR4_PGE + mov cr4, eax + + ; cr3 -> PML4TE0 + mov edx, edi + mov cr3, edx + + ; highs LME bit in EFER + mov ecx, MSR_IA32_EFER + rdmsr + or eax, 0x00000100 + wrmsr + + ; activate long mode + mov ebx, cr0 + or ebx, CR0_PG | CR0_PE + mov cr0, ebx + + cli + lgdt [gdt_descriptor] + + jmp 0x08:lm_start + +error: + mov si, .msg + call print + .msg db "err ", 0x00 + ret + +done: + hlt + jmp done + +print: + pushad + .loop + lodsb + test al, al + je .done + mov ah, 0x0E + int 0x10 + jmp .loop + .done + popad + ret + +; TODO make readable (yoinked from https://wiki.osdev.org/Entering_Long_Mode_Directly) +gdt_data: + dq 0x0000000000000000 + dq 0x00209A0000000000 + dq 0x0000920000000000 + +gdt_descriptor: + dw $ - gdt_data - 1 ; size + dd gdt_data ; start + +[bits 64] + +; long mode entry +lm_start: + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + ; set up serial device + ; TODO poll and whatnot (in rust??) + mov dx, 0x3F8 + + ; qemu -no-graphic overlaps serial and bios output without this + mov al, 0x0D + out dx, al + mov al, 0x0A + out dx, al + + ; initialize IDT at IDT_ADDR + call idt_init + + int3 ; silly test + + jmp KERNEL_LOAD_ADDR_ES * 0x10 + +idt_init: + ; clear space for idt + mov rdi, IDT_ADDR + push di + mov rcx, IDT_SIZE / 4 + xor rax, rax + cld + rep stosd ; clear double word for each rcx + pop di + + push rdx ; dx contains the output device + ; nothing between here and the `pop rdx` will be able to print + + ; breakpoint + mov rdi, 0x8E ; present, no dpl, interrupt + mov rsi, 0x03 ; breakpoint interrupt + lea rdx, [int_hdl_dummy] + call mk_idt_entry + + pop rdx ; get back dx output device + + lidt [idt_descriptor] + + ret + +int_hdl_dummy: + mov rsi, .msg + call lm_print + iretq + .msg db "INTdummy", 0x0D, 0x0A, 0x00 + +; rdi = flags +; rsi = entry number +; rdx -> handler +mk_idt_entry: + mov rax, rdx + mov rcx, rsi + + shl rcx, 4 ; offset = entry number * 16 + add rcx, IDT_ADDR + + mov word [rcx + 0], ax ; offset + mov word [rcx + 2], IDT_SEGMENT ; code segment + mov word [rcx + 5], di + mov byte [rcx + 4], 0 ; IST (0 = none) + shr rax, 16 + mov word [rcx + 6], ax ; offset + shr rax, 16 + mov dword [rcx + 8], eax ; offset + mov dword [rcx + 12], 0 ; reserved + ret + +lm_print: + .loop + mov al, [rsi] + test al, al + jz .done + out dx, al + inc si + jmp .loop + .done: + ret + +idt_descriptor: + dw IDT_SIZE - 1 ; size + dq IDT_ADDR ; start + +msg_a20_line db "a20 line", 0x0D, 0x0A, 0x00 +msg_disk_read db "disk", 0x0D, 0x0A, 0x00 + +times 510-($-$$) db 0 ; 2 bytes less now +db 0x55 +db 0xAA diff --git a/bootler/asm/kernel.asm b/bootler/asm/kernel.asm new file mode 100644 index 0000000..b4cbb30 --- /dev/null +++ b/bootler/asm/kernel.asm @@ -0,0 +1,23 @@ +[bits 64] + +mov al, 'K' +out dx, al +mov al, 'e' +out dx, al +mov al, 'r' +out dx, al +mov al, 'n' +out dx, al +mov al, 'e' +out dx, al +mov al, 'l' +out dx, al +mov al, 0x0D +out dx, al +mov al, 0x0A +out dx, al +mov al, 0x00 +out dx, al +.done + hlt + jmp .done diff --git a/bootler/package.nix b/bootler/package.nix new file mode 100644 index 0000000..4e18816 --- /dev/null +++ b/bootler/package.nix @@ -0,0 +1,49 @@ +{ + stdenv, + nasm, + qemu, + ... +}: let + bootImg = "boot"; +in + stdenv.mkDerivation { + pname = "bootler"; + version = "0.1.0"; + src = ./.; + buildPhase = '' + ${nasm}/bin/nasm asm/boot.asm -o boot.bin + ${nasm}/bin/nasm asm/kernel.asm -o dummy.bin + + dd if=/dev/zero of=${bootImg} bs=512 count=2 + dd if=boot.bin of=${bootImg} conv=notrunc + dd if=dummy.bin of=${bootImg} bs=512 seek=1 conv=notrunc + ''; + installPhase = '' + mkdir -p $out/bin + cp boot.bin $out/bin + cp dummy.bin $out/bin + cp ${bootImg} $out/bin + + # create emulation binary + cat<$out/bin/bootler + #!/usr/bin/env bash + + # create temp dir + mkdir -p ./.bootler + cp $(echo $out)/bin/${bootImg} ./.bootler/${bootImg} + chmod a+w ./.bootler/${bootImg} + + # run image + ${qemu}/bin/qemu-system-x86_64 \ + -nographic \ + -drive file=./.bootler/${bootImg},format=raw,index=0,media=disk + + # clean up + rm ./.bootler -r + + EOF + + chmod +x $out/bin/${bootImg} + chmod +x $out/bin/bootler + ''; + } diff --git a/flake.nix b/flake.nix index 81b9289..a631534 100644 --- a/flake.nix +++ b/flake.nix @@ -18,14 +18,15 @@ ... }: let system = "x86_64-linux"; - pkgs = import nixpkgs { + pkgs = nixpkgs.legacyPackages.${system}; + pkgsWithRustOverlay = import nixpkgs { inherit system; overlays = [(import rust-overlay)]; }; in { packages.${system} = { - bootler = pkgs.callPackage ./nix/pkgs/bootler.nix {}; - bootle = pkgs.callPackage ./nix/pkgs/bootle.nix { + bootler = pkgs.callPackage ./bootler/package.nix {}; + bootle = pkgsWithRustOverlay.callPackage ./bootle/package.nix { naersk = naersk; bootler = self.packages.${system}.bootler; }; diff --git a/nix/package.nix b/nix/package.nix deleted file mode 100644 index 3d56a51..0000000 --- a/nix/package.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ - stdenv, - nasm, - qemu, - ... -}: let - bootImg = "boot"; -in - stdenv.mkDerivation { - pname = "bootler"; - version = "0.1.0"; - src = ../.; - buildPhase = '' - ${nasm}/bin/nasm asm/boot.asm -o boot.bin - ${nasm}/bin/nasm asm/kernel.asm -o kernel.bin - - dd if=/dev/zero of=${bootImg} bs=512 count=2 - dd if=boot.bin of=${bootImg} conv=notrunc - dd if=kernel.bin of=${bootImg} bs=512 seek=1 conv=notrunc - ''; - installPhase = '' - mkdir -p $out/bin - cp ${bootImg} $out/bin - - # create emulation binary - cat<$out/bin/bootler - #!/usr/bin/env bash - - # create temp dir - mkdir -p ./.bootler - cp $(echo $out)/bin/${bootImg} ./.bootler/${bootImg} - chmod a+w ./.bootler/${bootImg} - - # run image - ${qemu}/bin/qemu-system-x86_64 \ - -nographic \ - -drive file=./.bootler/${bootImg},format=raw,index=0,media=disk - - # clean up - rm ./.bootler -r - - EOF - - chmod +x $out/bin/${bootImg} - chmod +x $out/bin/bootler - ''; - } diff --git a/nix/pkgs/bootle.nix b/nix/pkgs/bootle.nix deleted file mode 100644 index 99bdb55..0000000 --- a/nix/pkgs/bootle.nix +++ /dev/null @@ -1,68 +0,0 @@ -{ - callPackage, - rust-bin, - naersk, - bootler, - qemu, - ... -}: let - rust-toolchain = rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml; - naersk' = callPackage naersk { - cargo = rust-toolchain; - rustc = rust-toolchain; - clippy = rust-toolchain; - }; -in (naersk'.buildPackage { - src = ../../.; - - # deps for rust-src - additionalCargoLock = "${rust-toolchain.availableComponents.rust-src}/lib/rustlib/src/rust/library/Cargo.lock"; - - # just library build - copyBins = false; - copyLibs = true; - release = true; - - # build std - cargoBuildOptions = x: - x - ++ [ - "-Zbuild-std" - ]; - - postInstall = '' - ld --oformat binary \ - -o kernel.bin \ - -T src/linker.ld \ - -e _start \ - target/x86_64-unknown-none/release/libbootle.a - - dd if=/dev/zero of=disk bs=512 count=2 - dd if=${bootler}/bin/boot.bin of=disk conv=notrunc - dd if=kernel.bin of=disk bs=512 seek=1 conv=notrunc - - mkdir -p $out/lib - mkdir -p $out/bin - - cat<$out/bin/bootle - #!/usr/bin/env bash - - mkdir -p ./.bootle - cp $(echo $out)/bin/disk ./.bootle/disk - chmod a+w ./.bootle/disk - - ${qemu}/bin/qemu-system-x86_64 \ - -nographic \ - -drive file=./.bootle/disk,format=raw,index=0,media=disk - - rm ./.bootle -r - - EOF - - chmod +x $out/bin/bootle - - cp target/x86_64-unknown-none/release/libbootle.a $out/lib - cp kernel.bin $out/bin - cp disk $out/bin - ''; -}) diff --git a/nix/pkgs/bootler.nix b/nix/pkgs/bootler.nix deleted file mode 100644 index 3e5d2e4..0000000 --- a/nix/pkgs/bootler.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - stdenv, - nasm, - qemu, - ... -}: let - bootImg = "boot"; -in - stdenv.mkDerivation { - pname = "bootler"; - version = "0.1.0"; - src = ../../.; - buildPhase = '' - ${nasm}/bin/nasm asm/boot.asm -o boot.bin - ${nasm}/bin/nasm asm/kernel.asm -o dummy.bin - - dd if=/dev/zero of=${bootImg} bs=512 count=2 - dd if=boot.bin of=${bootImg} conv=notrunc - dd if=dummy.bin of=${bootImg} bs=512 seek=1 conv=notrunc - ''; - installPhase = '' - mkdir -p $out/bin - cp boot.bin $out/bin - cp dummy.bin $out/bin - cp ${bootImg} $out/bin - - # create emulation binary - cat<$out/bin/bootler - #!/usr/bin/env bash - - # create temp dir - mkdir -p ./.bootler - cp $(echo $out)/bin/${bootImg} ./.bootler/${bootImg} - chmod a+w ./.bootler/${bootImg} - - # run image - ${qemu}/bin/qemu-system-x86_64 \ - -nographic \ - -drive file=./.bootler/${bootImg},format=raw,index=0,media=disk - - # clean up - rm ./.bootler -r - - EOF - - chmod +x $out/bin/${bootImg} - chmod +x $out/bin/bootler - ''; - } diff --git a/rust-toolchain.toml b/rust-toolchain.toml deleted file mode 100644 index 22068c5..0000000 --- a/rust-toolchain.toml +++ /dev/null @@ -1,5 +0,0 @@ -[toolchain] -channel = "nightly" -components = ["rust-src"] -targets = ["x86_64-unknown-none"] -profile = "default" diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index adc1aab..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,55 +0,0 @@ -#![no_std] -#![no_main] - -use core::panic::PanicInfo; - -#[unsafe(no_mangle)] -pub extern "C" fn _start() -> ! { - welcome_serial(); - halt() -} - -fn print_serial(s: &str) { - let mut bytes = s.bytes(); - while let Some(b) = bytes.next() { - unsafe { - core::arch::asm!( - "out dx, al" - , in("al") b - ) - }; - } -} - -fn println_serial(s: &str) { - print_serial(s); - print_serial("\n"); -} - -fn welcome_serial() { - print_serial(ANSI_PINK); - println_serial("\nWelcome to Bootle OS"); - println_serial("All code GPL licensed and freely available on git.mtgmonkey.net"); - print_serial("Enjoy your time! Press "); - print_serial(ANSI_RED); - print_serial("ctrl+a x"); - print_serial(ANSI_PINK); - println_serial(" to escape Qemu"); - print_serial(ANSI_CLEAR); -} - -#[panic_handler] -fn panic(_: &PanicInfo) -> ! { - print_serial("panicked"); - halt() -} - -fn halt() -> ! { - unsafe { core::arch::asm!("hlt") }; - halt() -} - -const ANSI_CLEAR: &str = "\x1b[0m"; -const ANSI_RED: &str = "\x1b[31m"; -const ANSI_PINK: &str = "\x1b[35m"; -const ANSI_GREEN: &str = "\x1b[32m"; diff --git a/src/linker.ld b/src/linker.ld deleted file mode 100644 index b523bc5..0000000 --- a/src/linker.ld +++ /dev/null @@ -1,8 +0,0 @@ -SECTIONS -{ - . = 0x00010000; - .text : { - *(.text._start) - *(.text*) - } -} -- cgit v1.3.1