0

I've done my fair share of researching and have had a look at similar questions, but I can't seem to find anything useful. I'm pretty new to this, but I have a decent understanding of what's going on in the assembly code and why.

Basically, the boot sector here runs just fine in QEMU but my PC can't boot into it. It seems to get stuck in a loop, with just the blinking underscore on screen.

Neither MSG_REAL_MODE nor MSG_PROT_MODE get printed to screen (or if they do, they get cleared instantly).

There are a few different files with this one. I know it's a lot, sorry about that! If you need any clarification about anything, let me know :)

boot.asm (the main boot file)

[org 0x7c00]

  mov bp, 0x9000
  mov sp, bp
  
  mov bx, MSG_REAL_MODE
  call print_string
  
  call switch_to_pm
  
  jmp $
  
%include "f_print_string.asm"
%include "f_print_string_pm.asm"
%include "gdt.asm"
%include "f_switch_to_pm.asm"

[bits 32]
BEGIN_PM:

  mov ebx, MSG_PROT_MODE
  call print_string_pm
  
  jmp $
  
MSG_REAL_MODE: db "Started in 16-bit Real Mode", 0
MSG_PROT_MODE: db "Successfully landed in 32-bit Protected Mode", 0

times 510-($-$$) db 0
dw 0xaa55

f_print_string.asm (for printing strings in 16-bit Real Mode)

print_string:
  pusha
  
string_loop:
  mov al, [bx]
  cmp al, 0
  jne print_char
  popa
  ret
  
print_char:
  mov ah, 0x0e
  int 0x10
  add bx, 1
  jmp string_loop

f_print_string_pm.asm (for printing strings in 32-bit Protected Mode)

[bits 32]

VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f

print_string_pm:
  pusha
  mov edx, VIDEO_MEMORY
  
print_string_pm_loop:
  mov al, [ebx]
  mov ah, WHITE_ON_BLACK
  
  cmp al, 0
  je print_string_pm_done
  
  mov [edx], ax
  
  add ebx, 1
  add edx, 2
  
  jmp print_string_pm_loop
  
print_string_pm_done:
  popa
  ret

gdt.asm (for setting up the GDT and GDT descriptor, commented for better understanding)

; GDT
gdt_start:

gdt_null:
  dd 0x0
  dd 0x0
  
gdt_code:
  ; base=0x0, limit=0xfffff
  ; 1st flags: (present)1 (privilege)00 (descriptor type)1 -> 1001b
  ; type flags: (code)1 (conforming)0 (readable)1 (accessed)0 -> 1010b
  ; 2nd flags: (granularity)1 (32-bit default)1 (64-bit seg)0 (AVL)0 -> 1100b
  dw 0xffff     ; Limit (bits 0-15)
  dw 0x0        ; Base (bits 0-15)
  db 0x0        ; Base (bits 16-23)
  db 10011010b  ; 1st flags (4 bits) and type flags (4 bits)
  db 11001111b  ; 2nd flags (4 bits) and limit (4 bits)
  db 0x0        ; Base (bits 24-31)
  
gdt_data:
  ; Same as code segment except for the type flags:
  ; type flags: (code)0 (expand down)0 (writable)1 (accessed)0 -> 0010b
  dw 0xffff     ; Limit (bits 0-15)
  dw 0x0        ; Base (bits 0-15)
  db 0x0        ; Base (bits 16-23)
  db 10010010b  ; 1st flags (4 bits) and type flags (4 bits)
  db 11001111b  ; 2nd flags (4 bits) and limit (4 bits)
  db 0x0        ; Base (bits 24-31)
  
gdt_end:

; GDT descriptor
gdt_descriptor:
  dw gdt_end - gdt_start - 1
  dd gdt_start
  
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

f_switch_to_pm.asm (for switching to 32-bit Protected Mode)

[bits  16]

switch_to_pm:
  cli
  lgdt [gdt_descriptor]
  
  mov eax, cr0
  or eax, 0x1
  mov cr0, eax

  jmp CODE_SEG:init_pm

[bits 32]
init_pm:
  mov ax, DATA_SEG
  mov ds, ax
  mov ss, ax
  mov es, ax
  mov fs, ax
  mov gs, ax
  
  mov ebp, 0x90000
  mov esp, ebp
  
  call BEGIN_PM
  • 2
    A real PC often writes a BPB onto the boot sector copy loaded into RAM when booting. If you have code there instead of a BPB, that overwrites random pieces of your code. This comes up quite often, let me see if I can find a suitable duplicate. – fuz May 31 '21 at 13:36
  • @fuz Thanks for answering! Do you know of any way to stop the the code being overwritten by the BPB? Let me know if you have any luck finding a duplicate :D – Michael O'Connell May 31 '21 at 16:01
  • There is no way to stop this. As the linked duplicate says, you'll have to reserve the space occupied by the BPB and not touch it, unless you want to read disk parameters from it. – fuz May 31 '21 at 16:16
  • Ah, sorry! Didn't spot the duplicate. Thanks for your help! I'm assuming I can fill the space the BPB takes up with a bunch of zeros, then? – Michael O'Connell May 31 '21 at 16:27
  • Yes, zeroes, your own BPB... whatever you want. Just understand that the BIOS may overwrite it with “correct” disk parameters on boot. – fuz May 31 '21 at 16:40
  • Okay, just a quick update. I've tried adding in zeroes and I've tried with my own BPB. Neither seem to be working. What happens, basically, is the cursor underscore is flashing around at the very bottom of the screen. – Michael O'Connell Jun 07 '21 at 20:05
  • Oh, and I should mention, the code was working perfectly before I added the 32-bit-mode code without worrying about the BPB before. That's why I thought the code might be the issue :) – Michael O'Connell Jun 07 '21 at 20:24

0 Answers0