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]
 | 
			
		||||
build-std-features = ["compiler-builtins-mem"]
 | 
			
		||||
build-std = ["core", "compiler_builtins"]
 | 
			
		||||
 | 
			
		||||
[target.'cfg(target_os = "none")']
 | 
			
		||||
runner = "bootimage runner"
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,10 @@ steps:
 | 
			
		||||
  - name: build
 | 
			
		||||
    image: rustlang/rust:nightly
 | 
			
		||||
    commands:
 | 
			
		||||
      - cargo install bootimage
 | 
			
		||||
      - rustup component add llvm-tools-preview
 | 
			
		||||
      - rustup component add rust-src
 | 
			
		||||
      - make
 | 
			
		||||
      - cargo bootimage
 | 
			
		||||
 | 
			
		||||
  - name: release
 | 
			
		||||
    image: plugins/gitea-release
 | 
			
		||||
@ -14,6 +16,6 @@ steps:
 | 
			
		||||
      api_key:
 | 
			
		||||
        from_secret: api_key
 | 
			
		||||
      base_url: http://gitea_web_1:3000
 | 
			
		||||
      files: julios.iso
 | 
			
		||||
      files: target/x86_64-julios/debug/bootimage-julios.bin
 | 
			
		||||
    when:
 | 
			
		||||
      event: tag
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,5 +1 @@
 | 
			
		||||
/target
 | 
			
		||||
iso
 | 
			
		||||
*.iso
 | 
			
		||||
*.o
 | 
			
		||||
julios
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										9
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -2,6 +2,15 @@
 | 
			
		||||
# It is not intended for manual editing.
 | 
			
		||||
version = 3
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bootloader"
 | 
			
		||||
version = "0.9.19"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "b7c452074efc3c0bfb241fb7bc87df04741c7c85e926f6a07c05f8fbd6008240"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "julios"
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
[lib]
 | 
			
		||||
crate-type = ["staticlib"]
 | 
			
		||||
[dependencies]
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
#[no_mangle]
 | 
			
		||||
pub extern "C" fn julios_main() -> !
 | 
			
		||||
pub extern "C" fn _start() -> !
 | 
			
		||||
{
 | 
			
		||||
    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