I write boot.asm
kernel.asm
main.c
three file.
kernel.asm
and main.c
compile into kernel
file.
boot.asm
loader kernel into 0x10000
.
the question is kernel
file, the code 0f 01 15 22 00 00 00
, on objdump display lgdtl 0x22
, but when i run it on bochs, display lgdt ds:[di]
here are kernel.asm
global _start:
jmp _start
;====== gdt start
LABEL_GDT: dd 0,0
LABEL_DESC_CODE32:
dw 0xFFFF ;segment limit first 0-15 bits
dw 0x0000 ;base first 0-15 bits
db 0x00 ;base 16-23 bits
db 0b10011010 ;access byte
db 0b11001111 ;high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide)
db 0x00 ;base 24-31 bits
LABEL_DESC_DATA32:
dw 0xFFFF ;segment limit first 0-15 bits
dw 0x0000 ;base first 0-15 bits
db 0x00 ;base 16-23 bits
db 0b10010010 ;access byte
db 0b11001111 ;high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide)
db 0x00 ;base 24-31 bits
LABEL_DESC_VIDEO:
dw 0xFFFF ;segment limit first 0-15 bits
dw 0x8000 ;base first 0-15 bits
db 0x0B ;base 16-23 bits
db 0b10010010 ;access byte
db 0b11001111 ;high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide)
db 0x00 ;base 24-31 bits
LABEL_GDT_END:
GdtPtr dw LABEL_GDT_END - LABEL_GDT - 1
dd LABEL_GDT
SelectorCode equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
;======gdt end
_start:
Kernel_Start:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
lgdt [GdtPtr]
cli
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword SelectorCode:Kernel_Start32
;kernel entry protected
[BITS 32]
extern main
Kernel_Start32:
mov ax, SelectorVideo
mov gs, ax
mov edi, (80 * 11 + 10) * 2
mov ah, 0Ch
mov al, 'P'
mov [gs:edi], ax
call main
jmp $
main.c
int main() {
char *video = (char*)0x8b00;
int offset = 1440*10;
for (int i=0;i<20;i++) {
*(video+offset+i*4+0) = 0xff;
*(video+offset+i*4+1) = 0x00;
*(video+offset+i*4+2) = 0x00;
*(video+offset+i*4+2) = 0x00;
}
while (1) {
};
return 0;
}
compile command is
gcc -c main.c -o main.o -std=c99 -m32
nasm kernel.asm -f elf -o kernel.o
ld kernel.o main.o -e _start -o kernel -m elf_i386 -Ttext 0x10000 --oformat binary
result objdump -d kernel.o
is
result bochs run
is
This is because your code is assembled for 32 bit mode (which objdump
disassembles as, too) whereas you are still in 16 bit mode when _start
is executed. Bochs correctly disassembles for the current operation mode. As the addressing modes in 16 and 32 bit mode differ, the instruction's behaviour differs, too.
To fix this, temporarily switch the assembler to 16 bit mode with a bits 16
directive in the stub that switches to protected mode. You already have a bits 32
directive after that, so I'm not sure why you forgot the other one. Maybe you originally tested with a bin
format file which defaults to 16 bit mode. elf
format files default to 32 bit mode instead.