2

I am trying to create a simple bootloader that load my kernel in 32 bits mode. I read many articles and forums and write a bootsector 512 bytes and then a bootloader stage2. In stage 2, i can load gdt,A20,protected mode. but when i jump to 32 bits mode, it not working in qemu. I checked my code many times with different documents. Now I don't know that my codes has a bug or qemu is not working well. All of my codes in bootloader stage2:(My assembler is NASM)

bits 16
org 0x0
;-----------------------------------
jmp short main
; give the descriptor offsets names
%define NULL_DESC 0
%define CODE_DESC 0x8
%define DATA_DESC 0x10
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;---------------main---------------
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
main:
;------------------------------------setup segments and stack
cli     
;set up our segment registers to point to the segment in which we were         loaded – 2000    
mov ax, 2000h
mov ds, ax
mov es, ax
;setup stack in 9000
mov ax, 0x9000                  ; stack begins at 0x9000-0xffff
mov ss, ax
mov sp, 0xFFFF
sti                             ; Restore interrupts
cld                             ; The default direction for string operations will be 'up' - incrementing address in RAM
;------------------------------------install gdt
call InstallGDT
;------------------------------------enable A20 line
cli
push ax
mov al, 0xdd    ; send enable a20 address line command to controller
out 0x64, al
pop ax
;mov ax, 0x2401
;int 0x15
;mov ax, 0x3
;int 0x10
;------------------------------------enter to protected mode
cli
mov eax, cr0
or eax,0x1
mov cr0, eax
jmp CODE_DESC:BEGIN_PROTECTED_MODE

;------------------------------------halt the system
;cli
jmp $
;hlt


InstallGDT:
cli                             ; clear interrupts
pusha                           ; save registers
lgdt    [gdt_descriptor]        ; load GDT into GDTR
sti                             ; enable interrupts
popa                            ; restore registers
;-----------------------------------------------
gdt_data: 
dd 0                            ; null descriptor
dd 0 
; gdt code:             ; code descriptor
dw 0FFFFh           ; limit low
dw 0                ; base low
db 0                ; base middle
db 10011010b        ; access
db 11001111b        ; granularity
db 0                ; base high
; gdt data:             ; data descriptor
dw 0FFFFh           ; limit low (Same as code)10:56 AM 7/8/2007
dw 0                ; base low
db 0                ; base middle
db 10010010b        ; access
db 11001111b        ; granularity
db 0                ; base high
end_of_gdt:

; GDT descriptor
gdt_descriptor:
dw end_of_gdt - gdt_data - 1    ; limit (Size of GDT)
dd gdt_data                     ; base of GDT
;******************************************************
;   ENTRY POINT FOR 32 bits mode
;******************************************************
bits 32
BEGIN_PROTECTED_MODE:               ; after the switch we will get here
;Set registers  
  mov ax,DATA_DESC  
  mov ds, ax
  mov es, ax
 ;mov fs, ax
 ;mov gs, ax
 mov ss, ax
 mov esp,0x90000                    ; stack begins from 90000h
    ;cli
    ;hlt
;print a string
 mov esi,MSG_PROT_MODE
 mov ebx,0xb8000
.loop:
  lodsb
  or al,al
  jz halt
  or eax,0x0100
  mov word [ebx], ax
  add ebx,2
  jmp .loop
halt:
  cli
  hlt

MSG_PROT_MODE db "Loaded 32-bit protected mode", 0
madkne
  • 21
  • 1
  • 4
  • 1
    For one the base address in your `gdt_desciptor` needs to be a linear address. I surmise from the code you have loaded the code at 0x2000:0x0000. This represents physical address 0x20000. You are going to have to add 0x20000 to `gdt_data` to get a proper linear address. Your far jmp into protected mode also has to account for the fact that `BEGIN_PROTECTED_MODE` is relative to a base address of 0x20000 so you will need to add 0x20000 to `BEGIN_PROTECTED_MODE` to get a 32-bit linear address to jump to. – Michael Petch Jun 19 '18 at 07:00
  • @DavidHoelzer : he has a CLI instruction before enabling protected mode (4 lines before he does the FAR JMP to CODE_DESC:BEGIN_PROTECTED_MODE . His protected mode code doesn't re-enable it. – Michael Petch Jun 19 '18 at 14:55
  • 1
    I was looking at the InstallGDT function and then stopped looking. @MichaelPetch My bad. – David Hoelzer Jun 19 '18 at 15:03
  • I'm sorry ,ret ; All done! is not correct. this code was into another file and forgot for removing it. – madkne Jun 19 '18 at 23:41
  • Thank you for suggestions, but I examine these suggestions and not get an answer. – madkne Jun 19 '18 at 23:45
  • I don't see how removing the `ret` and having execution fall into the data in the GDT makes any sense. Why did you make that edit to your question? Now your code just has an obvious bug before it even reaches the `jmp far`. Single-step your code in a debugger (e.g. inside BOCHS, or with QEMU's gdb stub) – Peter Cordes Jun 19 '18 at 23:54

0 Answers0