Setup Kernel stack and reload register limit
Posted: Wed Oct 27, 2004 9:10 am
First question: How can I setup the kernel stack with another offset than the 0x0? I try it like that:
GDT.asm
_start.asm
If I try to boot the kernel it now happens (no text is print out etc.)
Second question: How can I reload the limit of the cs, ds, es, fs and gs register so that it all has a limit of 0xFFFFFFFF after I've enabled paging?
Third question: How is it possible that code is executed at 0x100000 but the limit of cs is only 0xFFFFF.
It might be that I've not understood the meanings of the registers correctly.
GDT.asm
Code: Select all
[BITS 32]
[EXTERN __stack]
gdt:
NULL_SELECTOR equ $-gdt
dd 0x00
dd 0x00
REALMODE_DATA_SELECTOR equ $-gdt
dw 0xFFFF ; limit bit 7 - 0 and 15 - 8
dw 0x0000 ; base 0 - 15
db 0x00 ; base 16 - 23
db 10010010b ; access byte
db 00000000b
db 0x00
DATA_SELECTOR equ $-gdt
dw 0xFFFF ; limit bit 7 - 0 and 15 - 8
dw 0x0000 ; base 0 - 15
db 0x00 ; base 16 - 23
db 10010010b ; access byte
db 11001111b
db 0x00
CODE_SELECTOR equ $-gdt
dw 0xFFFF ; limit bit 7 - 0 and 15 - 8
dw 0x0000 ; base 0 - 15
db 0x00 ; base 16 - 23
db 10011010b ; access byte
db 11001111b
db 0x00
STACK_SELECTOR equ $-gdt
dw 0x0000 ; limit bit 7 - 0 and 15 - 8
dw 0xFBFF ; base 0 - 15
db 0x08 ; base 16 - 23
db 10010010b ; access byte
db 11000001b
db 0x00 ; base 24 - 31
gdt_end:
gdt_desc:
dw gdt_end - gdt - 1
dd gdt
Code: Select all
[BITS 32]
[GLOBAL start]
[GLOBAL __kernel_mem_size]
[EXTERN _code]
[EXTERN _bss]
[EXTERN _end]
[EXTERN _main]
start:
jmp start2
%include 'gdt.asm'
MULTIBOOT_MAGIC equ 0x1BADB002
;MULTIBOOT_AOUT_KLUDGE equ 1 << 16
MULTIBOOT_FLAGS equ 0 ;MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)
__kernel_mem_size dd 0
start2:
cli
mov ecx, eax ; save the multiboot magic in ecx
mov [__kernel_mem_size], dword _end
lgdt [gdt_desc]
jmp dword CODE_SELECTOR:reload_cs
reload_cs:
mov eax, STACK_SELECTOR
mov ss, eax
mov esp, 0xFFFF
mov eax, DATA_SELECTOR
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
push ebx
push ecx
call _main
halt:
cli
hlt
jmp halt
align 4
multiboot_header:
magic dd MULTIBOOT_MAGIC
flags dd MULTIBOOT_FLAGS
checksum dd MULTIBOOT_CHECKSUM
; header_addr dd multiboot_header
; load_addr dd _code
; load_end_addr dd _bss
; bss_end_addr dd _end
; entry_addr dd start
Second question: How can I reload the limit of the cs, ds, es, fs and gs register so that it all has a limit of 0xFFFFFFFF after I've enabled paging?
Third question: How is it possible that code is executed at 0x100000 but the limit of cs is only 0xFFFFF.
It might be that I've not understood the meanings of the registers correctly.