Compare commits
No commits in common. "fafe05c251d322deaf5a2782ea489f06a0cc74e5" and "b3edf358550a64a00cb10d5e67bbfdb4cad44a9a" have entirely different histories.
fafe05c251
...
b3edf35855
@ -4,3 +4,6 @@ target = "x86_64-julios.json"
|
|||||||
[unstable]
|
[unstable]
|
||||||
build-std-features = ["compiler-builtins-mem"]
|
build-std-features = ["compiler-builtins-mem"]
|
||||||
build-std = ["core", "compiler_builtins"]
|
build-std = ["core", "compiler_builtins"]
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "none")']
|
||||||
|
runner = "bootimage runner"
|
||||||
|
@ -5,8 +5,10 @@ steps:
|
|||||||
- name: build
|
- name: build
|
||||||
image: rustlang/rust:nightly
|
image: rustlang/rust:nightly
|
||||||
commands:
|
commands:
|
||||||
|
- cargo install bootimage
|
||||||
|
- rustup component add llvm-tools-preview
|
||||||
- rustup component add rust-src
|
- rustup component add rust-src
|
||||||
- make
|
- cargo bootimage
|
||||||
|
|
||||||
- name: release
|
- name: release
|
||||||
image: plugins/gitea-release
|
image: plugins/gitea-release
|
||||||
@ -14,6 +16,6 @@ steps:
|
|||||||
api_key:
|
api_key:
|
||||||
from_secret: api_key
|
from_secret: api_key
|
||||||
base_url: http://gitea_web_1:3000
|
base_url: http://gitea_web_1:3000
|
||||||
files: julios.iso
|
files: target/x86_64-julios/debug/bootimage-julios.bin
|
||||||
when:
|
when:
|
||||||
event: tag
|
event: tag
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1 @@
|
|||||||
/target
|
/target
|
||||||
iso
|
|
||||||
*.iso
|
|
||||||
*.o
|
|
||||||
julios
|
|
||||||
|
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -2,6 +2,15 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bootloader"
|
||||||
|
version = "0.9.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7c452074efc3c0bfb241fb7bc87df04741c7c85e926f6a07c05f8fbd6008240"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "julios"
|
name = "julios"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bootloader",
|
||||||
|
]
|
||||||
|
@ -5,5 +5,5 @@ edition = "2018"
|
|||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[lib]
|
[dependencies]
|
||||||
crate-type = ["staticlib"]
|
bootloader = "0.9.8"
|
||||||
|
39
Makefile
39
Makefile
@ -1,39 +0,0 @@
|
|||||||
KERNEL = julios
|
|
||||||
ISO = julios.iso
|
|
||||||
INSTALL_ROOT = iso
|
|
||||||
ABS_INSTALL = $(abspath $(INSTALL_ROOT))
|
|
||||||
|
|
||||||
LINKER_SCRIPT = src/linker.ld
|
|
||||||
BOOT_OBJS = src/multiboot.o src/boot.o
|
|
||||||
LIB_JULIOS = target/x86_64-julios/debug/libjulios.a
|
|
||||||
|
|
||||||
GRUB_CFG = grub/grub.cfg
|
|
||||||
|
|
||||||
all: $(ISO)
|
|
||||||
|
|
||||||
$(ISO): install
|
|
||||||
./tools/create-iso.sh $@ $(INSTALL_ROOT)
|
|
||||||
|
|
||||||
install: $(KERNEL) $(GRUB_CFG)
|
|
||||||
mkdir -p $(ABS_INSTALL)
|
|
||||||
mkdir -p $(ABS_INSTALL)/boot/grub
|
|
||||||
cp $(KERNEL) $(ABS_INSTALL)/boot
|
|
||||||
cp grub/grub.cfg $(ABS_INSTALL)/boot/grub
|
|
||||||
|
|
||||||
$(KERNEL): $(LIB_JULIOS) $(LINKER_SCRIPT) $(BOOT_OBJS)
|
|
||||||
ld -n -T $(LINKER_SCRIPT) -o $(KERNEL) $(BOOT_OBJS) $(LIB_JULIOS)
|
|
||||||
|
|
||||||
$(LIB_JULIOS):
|
|
||||||
cargo build
|
|
||||||
|
|
||||||
|
|
||||||
%.o: %.asm
|
|
||||||
nasm -f elf64 $^ -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(BOOT_OBJS)
|
|
||||||
$(RM) $(KERNEL)
|
|
||||||
$(RM) julios.iso
|
|
||||||
$(RM) -r iso
|
|
||||||
|
|
||||||
.PHONY: $(INSTALL_ROOT) install clean all
|
|
@ -1,4 +0,0 @@
|
|||||||
menuentry "julios" {
|
|
||||||
multiboot2 /boot/julios
|
|
||||||
boot
|
|
||||||
}
|
|
190
src/boot.asm
190
src/boot.asm
@ -1,190 +0,0 @@
|
|||||||
section .rodata
|
|
||||||
gdt64:
|
|
||||||
dq 0
|
|
||||||
.code: equ $ - gdt64
|
|
||||||
dq (1<<43) | (1<<44) | (1<<47) | (1<<53)
|
|
||||||
|
|
||||||
.pointer:
|
|
||||||
dw $ - gdt64 - 1
|
|
||||||
dq gdt64
|
|
||||||
|
|
||||||
|
|
||||||
global _start
|
|
||||||
section .text
|
|
||||||
bits 32
|
|
||||||
|
|
||||||
_start:
|
|
||||||
mov esp, stack_top
|
|
||||||
|
|
||||||
call check_multiboot
|
|
||||||
call check_cpuid
|
|
||||||
call check_long_mode
|
|
||||||
|
|
||||||
call set_up_page_tables
|
|
||||||
call enable_paging
|
|
||||||
|
|
||||||
lgdt [gdt64.pointer]
|
|
||||||
jmp gdt64.code:long_mode_start
|
|
||||||
|
|
||||||
set_up_page_tables:
|
|
||||||
; map first P4 entry to P3 table
|
|
||||||
mov eax, p3_table
|
|
||||||
or eax, 0b11 ; present + writable
|
|
||||||
mov [p4_table], eax
|
|
||||||
|
|
||||||
; map first P3 entry to P2 table
|
|
||||||
mov eax, p2_table
|
|
||||||
or eax, 0b11 ; present + writable
|
|
||||||
mov [p3_table], eax
|
|
||||||
|
|
||||||
; map each P2 entry to a huge 2MiB page
|
|
||||||
mov ecx, 0 ; counter variable
|
|
||||||
|
|
||||||
.map_p2_table:
|
|
||||||
; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx
|
|
||||||
mov eax, 0x200000 ; 2MiB
|
|
||||||
mul ecx ; start address of ecx-th page
|
|
||||||
or eax, 0b10000011 ; present + writable + huge
|
|
||||||
mov [p2_table + ecx * 8], eax ; map ecx-th entry
|
|
||||||
|
|
||||||
inc ecx ; increase counter
|
|
||||||
cmp ecx, 512 ; if counter == 512, the whole P2 table is mapped
|
|
||||||
jne .map_p2_table ; else map the next entry
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
enable_paging:
|
|
||||||
; load P4 to cr3 register (cpu uses this to access the P4 table)
|
|
||||||
mov eax, p4_table
|
|
||||||
mov cr3, eax
|
|
||||||
|
|
||||||
; enable PAE-flag in cr4 (Physical Address Extension)
|
|
||||||
mov eax, cr4
|
|
||||||
or eax, 1 << 5
|
|
||||||
mov cr4, eax
|
|
||||||
|
|
||||||
; set the long mode bit in the EFER MSR (model specific register)
|
|
||||||
mov ecx, 0xC0000080
|
|
||||||
rdmsr
|
|
||||||
or eax, 1 << 8
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
; enable paging in the cr0 register
|
|
||||||
mov eax, cr0
|
|
||||||
or eax, 1 << 31
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Prints `ERR: ` and the given error code to screen and hangs.
|
|
||||||
; parameter: error code (in ascii) in al
|
|
||||||
error:
|
|
||||||
mov dword [0xb8000], 0x4f524f45
|
|
||||||
mov dword [0xb8004], 0x4f3a4f52
|
|
||||||
mov dword [0xb8008], 0x4f204f20
|
|
||||||
mov byte [0xb800a], al
|
|
||||||
hlt
|
|
||||||
|
|
||||||
|
|
||||||
check_multiboot:
|
|
||||||
cmp eax, 0x36d76289
|
|
||||||
jne .no_multiboot
|
|
||||||
ret
|
|
||||||
.no_multiboot:
|
|
||||||
mov al, "0"
|
|
||||||
jmp error
|
|
||||||
|
|
||||||
|
|
||||||
check_cpuid:
|
|
||||||
; Check if CPUID is supported by attempting to flip the ID bit (bit 21)
|
|
||||||
; in the FLAGS register. If we can flip it, CPUID is available.
|
|
||||||
|
|
||||||
; Copy FLAGS in to EAX via stack
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
; Copy to ECX as well for comparing later on
|
|
||||||
mov ecx, eax
|
|
||||||
|
|
||||||
; Flip the ID bit
|
|
||||||
xor eax, 1 << 21
|
|
||||||
|
|
||||||
; Copy EAX to FLAGS via the stack
|
|
||||||
push eax
|
|
||||||
popfd
|
|
||||||
|
|
||||||
; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported)
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
; Restore FLAGS from the old version stored in ECX (i.e. flipping the
|
|
||||||
; ID bit back if it was ever flipped).
|
|
||||||
push ecx
|
|
||||||
popfd
|
|
||||||
|
|
||||||
; Compare EAX and ECX. If they are equal then that means the bit
|
|
||||||
; wasn't flipped, and CPUID isn't supported.
|
|
||||||
cmp eax, ecx
|
|
||||||
je .no_cpuid
|
|
||||||
ret
|
|
||||||
.no_cpuid:
|
|
||||||
mov al, "1"
|
|
||||||
jmp error
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
check_long_mode:
|
|
||||||
; test if extended processor info in available
|
|
||||||
mov eax, 0x80000000 ; implicit argument for cpuid
|
|
||||||
cpuid ; get highest supported argument
|
|
||||||
cmp eax, 0x80000001 ; it needs to be at least 0x80000001
|
|
||||||
jb .no_long_mode ; if it's less, the CPU is too old for long mode
|
|
||||||
|
|
||||||
; use extended info to test if long mode is available
|
|
||||||
mov eax, 0x80000001 ; argument for extended processor info
|
|
||||||
cpuid ; returns various feature bits in ecx and edx
|
|
||||||
test edx, 1 << 29 ; test if the LM-bit is set in the D-register
|
|
||||||
jz .no_long_mode ; If it's not set, there is no long mode
|
|
||||||
ret
|
|
||||||
.no_long_mode:
|
|
||||||
mov al, "2"
|
|
||||||
jmp error
|
|
||||||
|
|
||||||
|
|
||||||
section .bss
|
|
||||||
align 4096
|
|
||||||
p4_table:
|
|
||||||
resb 4096
|
|
||||||
p3_table:
|
|
||||||
resb 4096
|
|
||||||
p2_table:
|
|
||||||
resb 4096
|
|
||||||
|
|
||||||
stack_bottom:
|
|
||||||
resb 64
|
|
||||||
stack_top:
|
|
||||||
|
|
||||||
|
|
||||||
global long_mode_start
|
|
||||||
section .text
|
|
||||||
bits 64
|
|
||||||
|
|
||||||
long_mode_start:
|
|
||||||
; load 0 into all data segment registers
|
|
||||||
mov ax, 0
|
|
||||||
mov ss, ax
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
extern julios_main
|
|
||||||
call julios_main
|
|
||||||
|
|
||||||
mov rax, 0x2f592f412f4b2f4f
|
|
||||||
mov qword [0xb8000], rax
|
|
||||||
.loop:
|
|
||||||
jmp .loop
|
|
@ -1,16 +0,0 @@
|
|||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
. = 1M;
|
|
||||||
|
|
||||||
.boot :
|
|
||||||
{
|
|
||||||
/* ensure that the multiboot header is at the beginning */
|
|
||||||
*(.multiboot_header)
|
|
||||||
}
|
|
||||||
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
*(.text)
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,7 +10,7 @@ fn panic(_info: &core::panic::PanicInfo) -> !
|
|||||||
static HELLO: &[u8] = b"Welcome to the JuliOS";
|
static HELLO: &[u8] = b"Welcome to the JuliOS";
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn julios_main() -> !
|
pub extern "C" fn _start() -> !
|
||||||
{
|
{
|
||||||
let vga_buffer: *mut u8 = 0xb8000 as *mut u8;
|
let vga_buffer: *mut u8 = 0xb8000 as *mut u8;
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
section .multiboot_header
|
|
||||||
header_start:
|
|
||||||
dd 0xe85250d6 ; magic number (multiboot 2)
|
|
||||||
dd 0 ; architecture 0 (protected mode i386)
|
|
||||||
dd header_end - header_start ; header length
|
|
||||||
; checksum
|
|
||||||
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
|
|
||||||
|
|
||||||
; insert optional multiboot tags here
|
|
||||||
|
|
||||||
; required end tag
|
|
||||||
dw 0 ; type
|
|
||||||
dw 0 ; flags
|
|
||||||
dd 8 ; size
|
|
||||||
header_end:
|
|
@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
iso_filename=$1
|
|
||||||
base_dir=$2
|
|
||||||
|
|
||||||
unset MFLAGS MAKEFLAGS
|
|
||||||
|
|
||||||
grub-mkrescue -o $iso_filename $base_dir
|
|
Loading…
Reference in New Issue
Block a user