os-k/boot/loader/loader.asm

234 lines
6.6 KiB
NASM

;=----------------------------------------------------------------------------=;
; GNU GPL OS/K ;
; ;
; Authors: spectral` ;
; NeoX ;
; ;
; Desc: Kernel (second stage) Loader for OS/K ;
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
[BITS 16]
[ORG 0x1000]
mov ax, cs ; correcting cs after the horrible far jump
mov ds, ax ; hm... And ds too
mov es, ax ; And es because it is jealous
mov [Bootdrv], dl
xor dl, dl
jmp 0x0000:main
%include "boot/loader/cpu/cpuid.asm"
%include "boot/loader/io/rmterm.asm"
%include "boot/loader/io/rmmem.asm"
main:
;; compatibility check
push si
mov si, Init
call PrintB
pop si
call Is64bits
jc ErrorNo64
push si
mov si, Pass
call PrintB
pop si
;; Enabling A20
push si
mov si, EnA20
call PrintB
pop si
call set_a20
push si
mov si, Pass
call PrintB
pop si
;; DISABLING CURSOR BLINKING AND GETTING INFOS
call get_dimensions
call disable_cursor
;;GO GDT64
cli ; disable interrupts
lgdt [GDT64]
;; ACTIVATE PROTECTED MODE
mov eax, cr0
or al, 1b ; PE = 1
mov cr0, eax
;; DISABLE PAGING
mov eax, cr0
and eax, 0x7FFFFFFF ; PG = 0
; |0|111111111111111111111111111111
; |
; `------ Paging bit
mov cr0, eax
push dword [VIDEO_MODE]
push dword [VGA_HEIGHT]
jmp (CODE_SELECTOR-GDT64):main32
;; THE HOLE ----------------------------------------------------------------- ;;
ErrorNo64:
mov si, NoLongMode
call PrintB
Die:
cli
hlt ; die nooooow
jmp 0xF000:0xFFF0
;; END OF THE HOLE ---------------------------------------------------------- ;;
[BITS 32]
main32:
pop dword [VGA_HEIGHT32]
pop dword [VIDEO_MODE32]
;; VERIFY A20
pushad
mov edi,0x112345 ;odd megabyte address.
mov esi,0x012345 ;even megabyte address.
mov [esi],esi ;making sure that both addresses contain diffrent values.
mov [edi],edi ;(if A20 line is cleared the two pointers would point to the address 0x012345 that would contain 0x112345 (edi))
cmpsd ;compare addresses to see if the're equivalent.
popad
jne .A20_on ;if not equivalent , A20 line is set.
mov WORD [A20_OK], 0
jmp .A20_end
.A20_on:
mov BYTE [A20_OK], 1
.A20_end:
;; INITIALIZE PROTECTED MODE SEGMENT REGISTERS
mov ax, DATA_SELECTOR-GDT64
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
;; ACTIVATE PHYSICAL ADRESS EXTENSION
mov eax, cr4
or eax, 100000b ; PAE = 1 = 4 Mo / page. 0 = 4 Ko
mov cr4, eax
;;cleanup
mov edi, 0x70000
mov ecx, 0x10000
xor eax, eax
rep stosd
;;formatting
mov dword [0x70000], 0x71000 + 7 ; first PDP table
mov dword [0x71000], 0x72000 + 7 ; first page directory
mov dword [0x72000], 0x73000 + 7 ; first page table
mov edi, 0x73000 ; address of first page table
mov eax, 7
mov ecx, 256 ; number of pages to map (1 MB)
.make_page_entries:
stosd
add edi, 4
add eax, 0x1000
loop .make_page_entries
;; pointing pml4
mov eax, 0x70000 ; Bass address of PML4
mov cr3, eax ; load page-map level-4 base
;; ACTIVATE LONG MODE
mov ecx, 0xC0000080 ; address of MSR
rdmsr ; read MSR
or eax, 100000000b ; LME = 1. (Long Mode Enable)
wrmsr ; write MSR
;; ACTIVATE PAGING
mov eax, cr0
or eax, 0x80000000 ; make bit 31 (PG = Paging) to 1 :
; |1|000000000000000000000000000000
; |
; `------ Paging bit
mov cr0, eax
push dword 0
push dword [VIDEO_MODE]
push dword 0
push dword [VGA_HEIGHT]
jmp (LONG_SELECTOR-GDT64):main64
[BITS 64]
;; DATA
Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0
CPUIDD db 0x09, " Checking CPUID...", 0
EnA20 db 0x09, " Enabling A20 line...", 0
ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D,0
txt db 0x09, " Switching to Long Mode... ", 0
Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0
Pass db " OK", 0x0A, 0x0D, 0
Fail db " FAIL!", 0x0A, 0x0D, 0
msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0
FileNotFound db "Second Stage Error : The Kernel was not found.", 0x0A, 0x0D, 0
DiskError db "Second Stage Error : The Disk has crashed.", 0x0A, 0x0D, 0
filename db "KERNEL BIN"
%include "boot/loader/io/lmmem.asm"
%include "boot/loader/io/lmterm.asm"
%include "boot/loader/io/ata.asm"
%include "boot/loader/cpu/cpu.asm"
%include "boot/loader/fs/fat.asm"
main64:
pop qword [VGA_HEIGHT64]
pop qword [VIDEO_MODE64]
;; INITIALIZE STACK
mov rsp, 0x9F000
call clear
;; Printing
mov bl, 0x0B
mov esi, Reinit
call write
mov bl, 0x0F
mov esi, CPUIDD
call write
mov bl, 0x0A
mov esi, Pass
call write
mov bl, 0x0F
mov esi, EnA20
call write
call check_a20
mov bl, 0x0F
mov esi, txt
call write
mov bl, 0x0A
mov esi, Pass
call write
mov bl, 0x0D
mov esi, msg
call write
mov bl, 0x0F
mov esi, ReadAttempt
call write
call temporize ; Temporized because the ATA drive must be ready
call ata_read
jmp Die
; times 1024 nop
; XXX ;
; It seems impossible to have an executable > 2.0 kB...