Problems with NASM setup code in Protected Mode
Posted: Tue Apr 17, 2007 5:36 am
HI, I'm trying to make a boot loader in assembly NASM for a little OS following the bootloader of linux 0.1 by linus Torwalds.
I have a problem with LGDT instruction in PROTECTED MODE, because if i place the GDT structure or the GDT descriptor after the page directory and the page tables ( as Linus Torwalds do) at ORG 0x7000 (in poor words), the value loaded in the GDT register is not correct and i get an exception at run time trying to load DS. The code of the boot loader is loaded at 0x00000. But if i place GDT and GDT descriptor before Page directory (near 0x00000) it works well.
But in this way the paging setup will overwirte this low area because the page directory starts at 0x000000 and its entry will overwrite.
in PROTECTED MODE, with a GDT already correctly set:
[BITS 32] ; Tell NASM to assemble 32-bit code
startup_32:
mov eax,0x10 ; Load eax with 0x10(16=2*8) pointer in the GDT
mov es,ax
mov ds,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,pg_dir-4 ; Set the stack pointer
call setup_gdt
.....
.....
times 0x7000-($-$$) db 0 ; AFTER PAGE DIRECTORY AND PAGE TABLES
align 16
_gdt:
dd 0x00000000
dd 0x00000000 ; NULL descriptor
dw 0x0FFF ; second descriptor for kernel code segment 0xFFF (0x1000 - 1) 16MB
dw 0x0000 ; base address=0
dw 0x9A00 ; code, read/exec
dw 0x00C0 ; granularity=4096, 386
dw 0x0FFF ; third descriptor for kernel data segment 0xFFF (0x1000 - 1) 16MB
dw 0x0000 ; base address=0
dw 0x9200 ; data read/write
dw 0x00C0 ; granularity=4096, 386
dd 0x00000000
dd 0x00000000 ; TEMPORARY
times 506 dd 0
gdt_descr:
dw 0x7FF ; 256 entries
dd _gdt ; GDT address
setup_gdt:
; Procedure setup_gdt()
; Descritpion: Load the GDT descriptor.
lgdt [gdt_descr]
ret
The call to this procedure is not correct, because i guess it doesn't jump to the right location and then i get an exception.
What's the problem?
I have a problem with LGDT instruction in PROTECTED MODE, because if i place the GDT structure or the GDT descriptor after the page directory and the page tables ( as Linus Torwalds do) at ORG 0x7000 (in poor words), the value loaded in the GDT register is not correct and i get an exception at run time trying to load DS. The code of the boot loader is loaded at 0x00000. But if i place GDT and GDT descriptor before Page directory (near 0x00000) it works well.
But in this way the paging setup will overwirte this low area because the page directory starts at 0x000000 and its entry will overwrite.
in PROTECTED MODE, with a GDT already correctly set:
[BITS 32] ; Tell NASM to assemble 32-bit code
startup_32:
mov eax,0x10 ; Load eax with 0x10(16=2*8) pointer in the GDT
mov es,ax
mov ds,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,pg_dir-4 ; Set the stack pointer
call setup_gdt
.....
.....
times 0x7000-($-$$) db 0 ; AFTER PAGE DIRECTORY AND PAGE TABLES
align 16
_gdt:
dd 0x00000000
dd 0x00000000 ; NULL descriptor
dw 0x0FFF ; second descriptor for kernel code segment 0xFFF (0x1000 - 1) 16MB
dw 0x0000 ; base address=0
dw 0x9A00 ; code, read/exec
dw 0x00C0 ; granularity=4096, 386
dw 0x0FFF ; third descriptor for kernel data segment 0xFFF (0x1000 - 1) 16MB
dw 0x0000 ; base address=0
dw 0x9200 ; data read/write
dw 0x00C0 ; granularity=4096, 386
dd 0x00000000
dd 0x00000000 ; TEMPORARY
times 506 dd 0
gdt_descr:
dw 0x7FF ; 256 entries
dd _gdt ; GDT address
setup_gdt:
; Procedure setup_gdt()
; Descritpion: Load the GDT descriptor.
lgdt [gdt_descr]
ret
The call to this procedure is not correct, because i guess it doesn't jump to the right location and then i get an exception.
What's the problem?