Page 1 of 1
booting a simple kernel with grub
Posted: Mon Jun 11, 2007 4:22 pm
by anon19287473
I pulled together a small kernel, which sets up a gdt and prints some stuff on the screen, and it is a valid multboot elf file, which grub recognizes, however, when I boot it, I don't see the character being printed, I've attached the code. I've tried everything I can think of, I just can't figure out the problem. (Note, this is my first attempt at a protected mode OS, cut me some slack if its a stupid mistake).
EDIT: I've also attached the ld script I used.
I compiled it with the following commands:
Code: Select all
nasm -f elf -o kernel.o kernel.asm
ld -T kernel.ld kernel.o
Thanks in advance.
Posted: Tue Jun 12, 2007 1:28 am
by Combuster
The problem is probably here:
I think you confused realmode segments with linear offsets. The correct address is
Posted: Tue Jun 12, 2007 9:29 am
by anon19287473
Thanks, I'll try that. Still getting used to the whole protected mode thing
![Smile :)](./images/smilies/icon_smile.gif)
Posted: Tue Jun 12, 2007 4:46 pm
by anon19287473
Nope
![Sad :(](./images/smilies/icon_sad.gif)
, it still does't work. Any other ideas?
Posted: Tue Jun 12, 2007 5:18 pm
by jnc100
Your gdt is wrong:
Code: Select all
gdt:
;; NULL descriptor
TIMES 8 db 0
;; Unused descriptor
TIMES 9 db 0
the second one I guess is a typo, try TIMES 8 db 0 like previously.
Also,
Code: Select all
DATA_SEL equ $-gdt
dw 0xffff
dw 0
db 0
db 0x92
db 0xcf
db 0
DATA_SEL isn't the correct selector for that descriptor - you need to use, as its the third entry (entry number 2 in a zero-based list):
2 << 3 + RPL, where I assume RPL for you is 0
= 0x10
Plus keep the fix Combuster posted.
Regards,
John.
Posted: Tue Jun 12, 2007 6:04 pm
by anon19287473
I made those changes and it still won't work
Code: Select all
[BITS 32]
section .text
global start
start:
; mov esp, sys_stack
lgdt [gdtr]
mov ax, DATA_SEL
mov ds, ax
mov es, ax
mov ss, ax
mov fs, ax
mov gs, ax
mov word [gs:0xb8000], 0x641
jmp $
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
;; The Multiboot header
align 4
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd CHECKSUM
section .data
[BITS 16]
gdtr:
dw gdt_end - gdt - 1
dd gdt
gdt:
;; NULL descriptor
dw 0
dw 0
db 0
db 0
db 0
db 0
;; Unused descriptor
dw 0
dw 0
db 0
db 0
db 0
db 0
CODE_SEL equ $-gdt
dw 0xFFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0
DATA_SEL equ $-gdt
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt_end:
[BITS 32]
SECTION .bss
resb 8192 ; Reserve 8KBytes of memory for the stack
sys_stack:
With the same linker script. Note: I wrote out the empty GDT sels, to avoid similar problems
![Smile :)](./images/smilies/icon_smile.gif)
Posted: Wed Jun 13, 2007 3:23 am
by jnc100
Just noted in your linker script you're relocating to 0xc0000000. This means that the executable you're creating is expecting to be run at address 0xC0000000, whereas by the AT directive you're informing grub to actually load the sections at 0x100000. This means the memory access to load your gdt is wrong.
If you really want a higher half kernel, I suggest you follow the instructions in
Higher Half With GDT. You'll note that it defines a special section in the output, called .setup, which contains the gdt to be loaded, and specifies both the virtual and physical addresses to be at 1MB, whereas the rest of the sections (.text, .data and .bss) are loaded above 1MB but relocated to above 0xc0000000.
Regards,
John.