This repository has been archived by the owner on Feb 5, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 250e180
Showing
25 changed files
with
1,455 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# beeOS | ||
|
||
## Why? | ||
|
||
Why not? | ||
|
||
## What does it do? | ||
|
||
Well, have you ever wanted some computer which just prints the bee movie script? | ||
Now you have the possibility to. | ||
|
||
## How do I compile it? | ||
|
||
Glad you asked! First, you need some tools: | ||
|
||
- nasm | ||
- nightly rust (the one as of September 24th 2018 works fine) | ||
- xargo (cargo install xargo) | ||
- make | ||
- grub-mkrescue (bundled with GRUB2) | ||
- probably an x86_64 system to compile on, that's what I used | ||
|
||
How: | ||
|
||
```bash | ||
$ cd rust/beeos/ | ||
$ RUST_TARGET_PATH=$(pwd) xargo build --release --target x86_64-beeos | ||
$ cd ../../asm | ||
$ make build | ||
# want to run it with qemu-system-x86_64? | ||
$ make run | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
arch ?= x86_64 | ||
rust_target ?= $(arch)-beeos | ||
build_dir := build/$(arch) | ||
src_dir := src/arch/$(arch) | ||
grub_cfg := src/iso/boot/grub/grub.cfg | ||
asm_src := $(wildcard $(src_dir)/*.asm) | ||
asm_obj := $(patsubst $(src_dir)/%.asm, $(build_dir)/%.o, $(asm_src)) | ||
kernel := $(build_dir)/iso/boot/kernel.bin | ||
linker := $(src_dir)/link.ld | ||
rust_interface := ../rust/beeos/target/$(arch)-beeos/release/libbeeos.a | ||
iso := $(build_dir)/beeOS-$(arch).iso | ||
|
||
.PHONY: build | ||
build: $(build_dir) $(asm_obj) $(kernel) | ||
mkdir -p $(build_dir)/iso/boot/grub | ||
cp $(grub_cfg) $(build_dir)/iso/boot/grub | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -rf build | ||
|
||
$(build_dir): | ||
mkdir -p $(build_dir) | ||
cp -r src/iso $(build_dir)/iso | ||
|
||
$(build_dir)/%.o: $(src_dir)/%.asm | ||
mkdir -p $(build_dir) | ||
nasm -felf64 $< -o $@ | ||
|
||
$(rust_interface): | ||
|
||
.PHONY: kernel | ||
kernel: $(kernel) | ||
|
||
$(kernel): $(rust_interface) $(build_dir) $(asm_obj) $(linker) $(wildcard ../rust/beeos/src/*.rs) | ||
cd ../rust/beeos && RUST_TARGET_PATH=./ xargo build --release --target x86_64-beeos | ||
$(LD) -n -o $(kernel) -T $(linker) $(asm_obj) $(rust_interface) | ||
|
||
.PHONY: iso | ||
iso: $(iso) | ||
|
||
$(iso): $(kernel) $(grub_cfg) | ||
grub-mkrescue -o $(iso) $(build_dir)/iso | ||
|
||
.PHONY: run | ||
run: iso | ||
qemu-system-x86_64 -cdrom $(iso) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
global start | ||
|
||
section .text | ||
bits 32 | ||
;; DESCRIPTION: | ||
;; Starts the kernel and initialises all parts needed. | ||
;; It may at any point error, though it shouldn't on a supported system (x86_64, CPUID supported, long mode, and pages work). | ||
;; | ||
;; If this errors, it will halt the CPU. | ||
;; | ||
;; LINKS: | ||
;; `stack.asm` for `stack_top`, `setup_page_tables`, and `enable_paging` | ||
;; `gdt.asm` for `gdt64` | ||
;; `longmode_check.asm` for `check_long_mode` | ||
;; `longmode_initialise` for `long_mode_start` | ||
;; `cpuid_check.asm` for `check_cpuid` | ||
;; `error.asm` for `error` | ||
start: | ||
;; Create a stack | ||
extern stack_top | ||
mov esp, stack_top | ||
|
||
;; Declare `error` for all users | ||
extern error | ||
|
||
;; Verify that this was executed through multiboot2 | ||
extern check_multiboot | ||
call check_multiboot | ||
|
||
;; Verify that the `cpuid` instruction is available | ||
extern check_cpuid | ||
call check_cpuid | ||
|
||
;; Verify that longmode exists | ||
extern check_long_mode | ||
call check_long_mode | ||
|
||
;; Setup CPU memory paging | ||
extern setup_page_tables | ||
call setup_page_tables | ||
|
||
;; Enable the paging | ||
extern enable_paging | ||
call enable_paging | ||
|
||
;; Load the GDT | ||
extern gdt64.pointer | ||
lgdt [gdt64.pointer] | ||
|
||
;; Move to a 64-bit code segment | ||
extern long_mode_start | ||
extern gdt64.code_segment | ||
jmp gdt64.code_segment:long_mode_start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
global check_cpuid | ||
|
||
section .text | ||
bits 32 | ||
;; DESCRIPTION: | ||
;; Checks for if the CPUID instruction is available on the system. | ||
;; | ||
;; If the instruction is unavailable, it will jump to $.cpuid_absent. | ||
;; If it's present, it will `ret`. | ||
check_cpuid: | ||
pushfd ; Push flags to stack | ||
pop eax ; Pop stack to eax | ||
|
||
mov ecx, eax ; Copy eax to ecx for later cmp | ||
|
||
xor eax, 1 << 21 ; Flip the 21st bit (CPUID bit) | ||
|
||
push eax ; Push back to stack | ||
popfd ; Return the flags back to CPU | ||
|
||
pushfd ; Get the flags back | ||
pop eax ; Pop the flags to eax, it shouldn't be ecx | ||
|
||
push ecx ; Restore ecx | ||
popfd ; Flip the bit back if it was flipped | ||
|
||
cmp eax, ecx ; Check if the flags changed when getting back | ||
je .cpuid_absent ; Halt if the bit wasn't flipped | ||
ret ; Return if it was | ||
|
||
;; DESCRIPTION: | ||
;; Halts the CPU with the error code "1". | ||
;; | ||
;; LINKS: | ||
;; `error.asm` for `error` | ||
.cpuid_absent: | ||
mov al, "1" ; Move error "1" to `al` | ||
extern error ; Declare `error` for linking to `error.asm` | ||
jmp error ; Jump to `error` for halting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
global error | ||
|
||
section .text | ||
bits 32 | ||
;; DESCRIPTION: | ||
;; Prints "ERR: " to the screen together with the error code in `al`. | ||
;; The text is all white on a red background. | ||
;; | ||
;; This halts the CPU. | ||
;; | ||
;; VARIABLES: | ||
;; `al` - Error code in a single byte. | ||
error: | ||
;; 0x4f = red background on white text | ||
mov dword [0xb8000], 0x4f524f45 ; "R" then "E" (little endian) - white text, red background | ||
mov dword [0xb8004], 0x4f3a4f52 ; ":" then "R" (little endian) - white text, red background | ||
mov dword [0xb8008], 0x4f204f20 ; " " then " " (little endian) - white text, red background | ||
;; Write `al` to the byte right after the first space shown. | ||
;; The other space is still red and white, making this byte red and white. | ||
mov byte [0xb800a], al | ||
hlt ; Halt the CPU |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
global gdt64 | ||
global gdt64.code_segment | ||
global gdt64.pointer | ||
|
||
section .rodata | ||
bits 32 | ||
;; DESCRIPTION: | ||
;; This is a GDT table. Code should be executed in the gdt64.code_segment block. | ||
;; The top is at gdt64.pointer. | ||
;; | ||
;; I have no idea how this actually works, but it does, so let's leave it at that. | ||
gdt64: | ||
dq 0 | ||
.code_segment: equ $ - gdt64 | ||
dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) | ||
.pointer: | ||
dw $ - gdt64 - 1 | ||
dq gdt64 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
ENTRY(start) | ||
|
||
SECTIONS | ||
{ | ||
/* Load in the first megabyte of RAM */ | ||
. = 1M; | ||
|
||
/* Ensure the header is first */ | ||
.boot : { | ||
/* KEEP is used due to making sure that it won't be removed if | ||
the optimiser is used to remove unused symbols */ | ||
KEEP(*(.multiboot_header)) | ||
} | ||
|
||
/* Actually link the .text section, and that before initialised memory is */ | ||
.text : { | ||
*(.text) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
global check_long_mode | ||
|
||
section .text | ||
bits 32 | ||
;; DESCRIPTION: | ||
;; Checks if the CPU has support for long mode. | ||
;; | ||
;; If it doesn't, jump to .long_mode_absent. | ||
;; If it does, return to stack. | ||
;; | ||
;; REFERENCES: | ||
;; https://en.wikipedia.org/wiki/CPUID#EAX.3D80000001h:_Extended_Processor_Info_and_Feature_Bits | ||
check_long_mode: | ||
mov eax, 0x80000000 ; Set `eax` to `0x80000000` | ||
cpuid ; Get highest supported argument into `eax` | ||
cmp eax, 0x80000001 ; Compare `eax` to `0x80000001`; does extended function exist? | ||
jb .long_mode_absent ; Long mode doesn't have the ability to exist | ||
|
||
mov eax, 0x80000001 ; Set `eax` to `0x80000001`; argument for processor info | ||
cpuid ; Get info into `ecx` and `edx` | ||
test edx, 1 << 29 ; Check 29th bit, the long mode bit | ||
jz .long_mode_absent ; If it's false, there is no long more support | ||
ret | ||
|
||
;; DESCRIPTION: | ||
;; Hals the CPU with the error code "2". | ||
;; | ||
;; LINKS: | ||
;; `error.asm` for `error` | ||
.long_mode_absent: | ||
mov al, "2" ; Move error "2" to `al` | ||
extern error ; Declare `error` for linking to `error.asm` | ||
jmp error ; Jump to `error` for halting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
global long_mode_start | ||
|
||
section .text | ||
bits 64 | ||
;; DESCRIPTION: | ||
;; Starts to execute kernel code in 64 bit mode and initialises basic data. | ||
;; | ||
;; After execution, this halts the CPU. | ||
;; | ||
;; LINKS: | ||
;; The Rust part of the kernel for `rust_main` | ||
long_mode_start: | ||
;; Reload data segments for 64-bit use instead of 32 bit | ||
mov ax, 0 | ||
mov ss, ax | ||
mov ds, ax | ||
mov es, ax | ||
mov fs, ax | ||
mov gs, ax | ||
|
||
;; Starts the Rust part of the kernel. | ||
extern rust_main | ||
call rust_main | ||
|
||
hlt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
global check_multiboot | ||
|
||
section .text | ||
bits 32 | ||
;; DESCRIPTION: | ||
;; Checks whether the kernel is loaded in multiboot mode, version 2. | ||
;; | ||
;; If it isn't, jump to .multiboot_absent. | ||
;; If it is, return to stack. | ||
;; | ||
;; VARIABLES: | ||
;; `eax` - Given by GRUB2 once it starts the kernel | ||
check_multiboot: | ||
cmp eax, 0x36d76289 ; Check for magic value | ||
jne .multiboot_absent ; Jump if not true | ||
ret ; Return to stack | ||
|
||
;; DESCRIPTION: | ||
;; Halts the CPU with the error code "0". | ||
;; | ||
;; LINKS: | ||
;; `error.asm` for `error` | ||
.multiboot_absent: | ||
mov al, "0" ; Move error "0" to `al` | ||
extern error ; Declare `error` for linking to `error.asm` | ||
jmp error ; Jump to `error` for halting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
section .multiboot_header | ||
bits 32 | ||
|
||
;; DESCRIPTION: | ||
;; Header for the multiboot mode, version 2 protocol. | ||
;; All multiboot2 compatible bootloaders check for this in the kernel before boot. | ||
header_start: | ||
;; Multiboot 2 requires a magic number to be start | ||
;; That is the following DWORD: | ||
dd 0xe85250d6 | ||
|
||
;; The architecture `protected i368` is `0` and it must be provided in a DWORD: | ||
dd 0 | ||
|
||
;; The length of the rest of the header should be provided as a DWORD: | ||
dd header_end - header_start | ||
|
||
;; A checksum of the header should exist and should be a DWORD: | ||
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) | ||
|
||
;; Multiboot then wants us to end with some other magic values: | ||
dw 0 | ||
dw 0 | ||
dd 8 | ||
header_end: |
Oops, something went wrong.