Thank you for replying me!
Well, I did those modification in bootloader (implement drive reset, far jump, use32 setup correctly, change GDT descriptors order) and also wrote a simple kernel in assembly for testing if this error was in compiling and linking 'kernel.c', but seems it does not, nothing still happening. So, I've tried using a bootloader found at
http://www.osdever.net/tutorials/view/mixing-assembly-c, modifying some parametres and, guess what? Still nothing happening.... I think that is an Virtual Box's error emulating. I will try emulate it on Bonch or qemu, because it seems to be more trusty. This is my code with modifications:
Code:
;=====================================NASM HEADERS========================================
%define KSEG 0x0800 ; kernel segment
%define KOFF 0x0000 ; kernel offset
%define KSEC 2 ; kernel sector
%define GDT_LOCATION 0x00007E00
%define GDT_SIZE 0x00FF
;=========================================================================================
use16
org 0x7C00
jmp 0x0000:start
start:
sti ; enable bios interrupts
; Set stacks
mov ax, 0x0500
mov ss, ax
mov sp, 0x7BFF
; Driver reset
mov ah,0x00
mov dl,0x00
int 0x13
; read kernel to memory
mov ah, 0x02 ; interrupt subfunction: read disk
mov dl, 0 ; drive ( 00h = A: )
mov dh, 0 ; head
mov ch, 0 ; cylinder
mov cl, KSEC ; sector
mov al, 1 ; number of sectors to be read
mov bx, KSEG ; es:bx points to memory buffer's location
mov es, bx
mov bx, KOFF ; 0x0800:0x0000
int 13h ; disk interrupt
cli ; disable BIOS interrupt
push cs
pop ds
; initializates GDT
mov ax, GDT_SIZE
mov word[gdtr], ax ; load GDT size
mov eax, GDT_LOCATION
mov dword[gdtr + 2], eax ; load GDT offset
; Load GDT entries
mov ebx, dword[gdtr + 2]
mov edx, gdt
mov ecx, 6
fillgdt:
mov eax, dword[edx]
mov dword[ebx], eax
add ebx, 4
add edx, 4
loop fillgdt
xor ax, ax
mov ds, ax
lgdt [gdtr] ; load GDT register
; enter protected mode
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x08:pmode
use32
pmode:
; Load Kernel Code and Data Descriptors
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
jmp 0x08:0x8000 ; now kernel have control of system
;======================================VARIABLES==========================================
gdtr dw 0x0000 ; GDT size
dd 0x00000000 ; GDT location
gdt dw 0x0000, 0x0000, 0x0000, 0x0000 ; GDT entry null
dw 0xFFFF, 0x0000, 0x9A00, 0x00CF ; GDT entry kernel code
dw 0xFFFF, 0x0000, 0x9200, 0x00CF ; GDT entry kernel data
;====================================NASM DIRECTIVES======================================
; fill the end of sector with signature's boot
times 510-($-$$) db 0
db 0x55
db 0xAA
After all, i have some questions about loading kernel and GDT descriptors:
- Have I need to explicitly load all GDT descriptors, like I did in my code? Because I saw that a lot of people do something like:
Code:
xor ax, ax
mov ds, ax ; Set DS-register to 0 - used by lgdt
lgdt [gdt_desc] ; Load the GDT descriptor
...
...
gdt: ; Address for the GDT
gdt_null: ; Null Segment
dd 0
dd 0
gdt_code: ; Code segment, read/execute, nonconforming
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
gdt_data: ; Data segment, read/write, expand down
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end: ; Used to calculate the size of the GDT
gdt_desc: ; The GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt ; Address of the GDT
- When GDT is setup correctly and protected mode was loaded properly, data will be stored in segment that I've specified right? Ok, and if this is true, what is stack pointer function in this story (still the same)?