;=----------------------------------------------------------------------------=; ; GNU GPL OS/K ; ; ; ; Authors: spectral` ; ; NeoX ; ; ; ; Desc: Kernel (second stage) Loader for OS/K ; ; (x86_64 architecture only) ; ;=----------------------------------------------------------------------------=; %define DEBUG [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 %ifdef DEBUG ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D, 0 %else ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0 %endif txt db 0x09, " Switching to Long Mode... ", 0 EndOfLoader db "End of loader.bin. System will halt !", 0x0A, 0x0D, 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 mov bl, 1 mov bh, 1 call ata_read mov bl, 0x0D mov esi, EndOfLoader call write jmp Die times 20 db 0