Bootloader - LBA28 in Long Mode not working
Posted: Thu Aug 05, 2021 11:53 pm
After entering long mode from bootloader, copying the second sector in memory using LBA28 crashes the PC. The second sector was copied in memory in 32 bit mode. The crash happens when executing the instruction
Is there a separate instruction for 64 bit mode?
I'm using Bochs as emualtor
Code:
Code: Select all
rep insw
I'm using Bochs as emualtor
Code:
Code: Select all
; -- -----------------------------------------------------------------------------------------
; ----------------------------- Bootloader ( first sector ) ---------------------------------
; -------------------------------------------------------------------------------------------
org 7C00h
; ---------------------------------------- Video Mode --------------------------------------------
; video mode 80x25:
mov ah, 00h
mov al, 03h
int 10h
; hide blinking
mov ch, 32
mov ah, 1
int 10h
; ---------------------------------------- 64 Bit Mode --------------------------------------------
USE16
cli ; disable the interrupts, just in
; case they are not disabled yet
lgdt [cs:GDTR] ; load GDT register
mov eax,cr0 ; switch to protected mode
or al,1
mov cr0,eax
jmp CODE_SELECTOR:pm_start
NULL_SELECTOR = 0
DATA_SELECTOR = 1 shl 3 ; flat data selector (ring 0)
CODE_SELECTOR = 2 shl 3 ; 32-bit code selector (ring 0)
LONG_SELECTOR = 3 shl 3 ; 64-bit code selector (ring 0)
GDTR: ; Global Descriptors Table Register
dw 4*8-1 ; limit of GDT (size minus one)
dq GDT ; linear address of GDT
GDT rw 4 ; null desciptor
dw 0FFFFh,0,9200h,08Fh ; flat data desciptor
dw 0FFFFh,0,9A00h,0CFh ; 32-bit code desciptor
dw 0FFFFh,0,9A00h,0AFh ; 64-bit code desciptor
USE32
pm_start:
mov eax,DATA_SELECTOR ; load 4 GB data descriptor
mov ds,ax ; to all data segment registers
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov eax,cr4
or eax,1 shl 5
mov cr4,eax ; enable physical-address extensions
mov edi,70000h
mov ecx,4000h shr 2
xor eax,eax
rep stosd ; clear the page tables
mov dword [70000h],71000h + 111b ; first PDP table
mov dword [71000h],72000h + 111b ; first page directory
mov dword [72000h],73000h + 111b ; first page table
mov edi,73000h ; address of first page table
mov eax,0 + 111b
mov ecx,256 ; number of pages to map (1 MB)
make_page_entries:
stosd
add edi,4
add eax,1000h
loop make_page_entries
mov eax,70000h
mov cr3,eax ; load page-map level-4 base
mov ecx,0C0000080h ; EFER MSR
rdmsr
or eax,1 shl 8 ; enable long mode
wrmsr
mov eax,cr0
or eax,1 shl 31
mov cr0,eax ; enable paging
jmp LONG_SELECTOR:long_start
USE64
long_start:
; mov rax,'L O N G '
;mov [0B8000h],rax
; ---------------------------------------- Load Data --------------------------------------------
mov dx,0x1F1
mov al,0h
out dx,al
mov dx,1f2h
mov al,2 ; number of sectors to read
out dx,al
mov dx,1f3h
mov al,1 ; 4 8 8 [8]
out dx,al
mov dx,1f4h
mov al,0 ; 4 8 [8] 8
out dx,al
mov dx,1f5h ; 4 [8] 8 8
mov al,0
out dx,al
mov dx,0x1F6
mov al,0xE0
out dx,al
mov dx,1f7h
mov al,20h ; 20h read 30h write
out dx,al
mov ecx, 4
loop1:
mov dx, 1F7h
in al, dx
test al, 10000000b
jnz short retry
test al, 00001000b
jnz short data_ready
retry:
dec ecx
jg short loop1
loop2:
mov dx, 1F7h
in al, dx
test al, 10000000b ; Check BSY
jnz short loop2
test al, 00100001b ; Check ERR and DF
jnz short fail
data_ready:
mov dx, 0x1F0
mov cx, 256*2
mov edi, 2000000
rep insw
mov rax,'L O N G '
mov [0B8000h],rax
hlt
fail:
mov rax,'F A I L '
mov [0B8000h],rax
hlt
; fill witgh zeroes the rest
times 510-($-$$) db 0
dw 0xAA55
; -------------------------------------------------------------------------------------------
; ----------------------------- Kernel ( second sector ) ---------------------------------
; -------------------------------------------------------------------------------------------
org 0
mov rax,'L O N 3 '
mov [0B8000h],rax
hlt
times 512*3-($-$$) db 0