I'm not that familiar with MASM (which by the assembler directives is what I believe you're using), so I re-assembled your code as a flat binary in NASM,with some slight adjustments to the labeling due to the fact that NASM throws an error with multiple ORG directives unlike MASM.
It seems that the main issue is that the hard-drive loading subroutine is not getting all the data from the disk into memory. Using QEMU, when I inspected the memory location at 0x2710, it was not the right length ... there were simply zero's past the second-to-last long jump where you wanted to jump over "some code", causing the instruction pointer to run wild through memory. You can see in my adjusted code below, that I've reduced the number of zeroed bytes to jump over, and that seemed to be just enough to get everything into memory so that there were no issues when running in QEMU.
Other than the hard-drive loading subroutine, your GDT and IDT looked good (for what they were), and the jump to 32-bit protected mode seemed to work fine as well once all the code was loaded into memory and wasn't truncated.
Code: Select all
ORG 2710h
start_bs_code:
; video mode 80x25:
mov ah, 00h
mov al, 03h
int 10h
; hide blinking
mov ch, 32
mov ah, 1
int 10h
; initialise registers
mov ax , 0
mov ds , ax
mov es , ax
mov fs , ax
mov gs , ax
mov ss , ax
mov sp , 2710h ; 10 000 dec
mov bp , 2710h
xor eax , eax
xor ebx , ebx
xor ecx , ecx
xor edx , edx
xor edi , edi
xor esi , esi
; -------------------------- enter 32 bit mode ----------------------------
cli
lgdt [GDT_DESCRIPTOR_PTR]
mov eax, cr0
or eax, 0x1
mov cr0,eax
jmp 0x8:MODE32_OFFSET
; -------------------------------------- GDT --------------------------------------------
gdt_A:
NullDescriptor:
dq 0
CodeDescriptor: ; CodeDescriptor = 8
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
DataDescriptor: ; DataDescriptor = 16
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_B:
GDT_OFFSET_START equ (0x7C00 + (gdt_A - 0x2710))
GDT_DESCRIPTOR_PTR equ (0x7C00 + (gdt - 0x2710))
gdt:
dw gdt_B - gdt_A
dd GDT_OFFSET_START
; -------------------------------------- GDT --------------------------------------------
BITS 32
MODE32_OFFSET equ (0x7C00 + (Mode32 - 0x2710))
Mode32:
mov ax , 16 ; DataDescriptor
mov ds , ax
mov es , ax
mov fs , ax
mov gs , ax
mov ss , ax
mov esp , 9FAB0h ; 654 000 dec
mov ebp , 9FAB0h ; 654 000 dec
xor eax , eax
xor ebx , ebx
xor ecx , ecx
xor edx , edx
xor edi , edi
xor esi , esi
; -------------------------------------------------------------------------------------------
; print a character
mov byte[0xB8000], "1"
mov byte[0xB8001], 00011011b
; load sectors
call loadM
; jump to loaded code
jmp 8h:2710h ; 10 000 dec
loadM:
; load sectors
mov dx,0x1F1
mov al,0h
out dx,al
; sector count
mov dx,1f2h
mov al,10 ; number of sectors to read
out dx,al
; sector location
mov dx,1f3h
mov al,1
out dx,al
mov dx,1f4h
mov al,0
out dx,al
mov dx,1f5h
mov al,0
out dx,al
mov dx,1f6h
mov al,01000000b
out dx,al
; read/write command
mov dx,1f7h
mov al,20h ;20h - read 30h - write
out dx,al
WhaitRead:
in al,dx
test al,8
jz WhaitRead
mov cx,256
mov edi, 2710h ; location in RAM
mov dx,1f0h
rep insw
ret
end_bs_code:
; fill with zeroes the rest
times (510 - (end_bs_code - start_bs_code)) db 0
dw 0xAA55
; -------------------------------------------------------------------------------------------
; ---------------------------------- Kernel -----------------------------------
; -------------------------------------------------------------------------------------------
kernel_start:
lidt [IDT_PTR_OFFSET]
jmp 8:JUMP_OVER_IDT_OFFSET
; -------------------------------------- IDT --------------------------------------------
idt_A:
; Offset Low | Code Selector | Flags | Offset High
dw isr0 , 8 , 1000111000000000b , 0
dw isr1 , 8 , 1000111000000000b , 0
dw isr2 , 8 , 1000111000000000b ,0
dw isr3 , 8 , 1000111000000000b , 0
dw isr4 , 8 , 1000111000000000b , 0
dw isr5 , 8 , 1000111000000000b , 0
dw isr6 , 8 , 1000111000000000b , 0
dw isr7 , 8 , 1000111000000000b , 0
dw isr8 , 8 , 1000111000000000b , 0
dw isr9 , 8 , 1000111000000000b , 0
dw isr10 , 8 , 1000111000000000b , 0
dw isr11 , 8 , 1000111000000000b , 0
dw isr12 , 8 , 1000111000000000b , 0
dw isr13 , 8 , 1000111000000000b , 0
dw isr14 , 8 , 1000111000000000b , 0
dw isr15 , 8 , 1000111000000000b , 0
dw isr16 , 8 , 1000111000000000b , 0
dw isr17 , 8 , 1000111000000000b , 0
dw isr18 , 8 , 1000111000000000b , 0
dw isr19 , 8 , 1000111000000000b , 0
dw isr20 , 8 , 1000111000000000b , 0
dw isr21 , 8 , 1000111000000000b , 0
dw isr22 , 8 , 1000111000000000b , 0
dw isr23 , 8 , 1000111000000000b , 0
dw isr24 , 8 , 1000111000000000b , 0
dw isr25 , 8 , 1000111000000000b , 0
dw isr26 , 8 , 1000111000000000b , 0
dw isr27 , 8 , 1000111000000000b , 0
dw isr28 , 8 , 1000111000000000b , 0
dw isr29 , 8 , 1000111000000000b , 0
dw isr30 , 8 , 1000111000000000b , 0
dw isr31 , 8 , 1000111000000000b , 0
dw irq0 , 8 , 1000111000000000b , 0
dw irq1 , 8 , 1000111000000000b , 0
dw irq2 , 8 , 1000111000000000b , 0
dw irq3 , 8 , 1000111000000000b , 0
dw irq4 , 8 , 1000111000000000b , 0
dw irq5 , 8 , 1000111000000000b ,0
dw irq6 , 8 , 1000111000000000b , 0
dw irq7 , 8 , 1000111000000000b , 0
idt_B:
IDT_OFFSET equ (0x2710 + (idt_A - kernel_start))
IDT_PTR_OFFSET equ (0x2710 + (idt - kernel_start))
idt:
dw idt_B - idt_A
dd IDT_OFFSET
isr0: ; iret
isr1:
isr2:
isr3:
isr4:
isr5:
isr6:
isr7:
isr8:
isr9:
isr10:
isr11:
isr12:
isr13:
isr14:
isr15:
isr16:
isr17:
isr18:
isr19:
isr20:
isr21:
isr22:
isr23:
isr24:
isr25:
isr26:
isr27:
isr28:
isr29:
isr30:
isr31:
irq0: ; iret
irq1:
irq2:
irq3:
irq4:
irq5:
irq6:
irq7:
; -----------------------------------------------------------------------------------
JUMP_OVER_IDT_OFFSET equ (0x2710 + (JumpOverIDT - kernel_start))
JumpOverIDT:
JUMP_OVER_SOME_CODE_OFFSET equ (0x2710 + (JumpOverSomeCode - kernel_start))
jmp 8:JUMP_OVER_SOME_CODE_OFFSET
times 146 db 0 ; 498
JumpOverSomeCode:
mov byte[0xB8002], "2"
mov byte[0xB8003], 00011011b
jmp $