Access Variables in Kernel

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Pulser

Access Variables in Kernel

Post by Pulser »

I have a kernel loaded a 0x9000:0 but I can't seem to access variables in the .data section. All my code is in assembler at the moment. Is this a problem with the GDT? I've also seen a few asm kernels using a linker script? Could that be the problem because I dont have one? Also, a cpu_dump from the bochs debugger shows DS valid=7, whereas all the other segments are valid=1, could this be the problem? Thanks
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Access Variables in Kernel

Post by Brendan »

Hi,
Pulser wrote: I have a kernel loaded a 0x9000:0 but I can't seem to access variables in the .data section. All my code is in assembler at the moment. Is this a problem with the GDT? I've also seen a few asm kernels using a linker script? Could that be the problem because I dont have one? Also, a cpu_dump from the bochs debugger shows DS valid=7, whereas all the other segments are valid=1, could this be the problem? Thanks
I don't use a linker script either (my kernel is 100% NASM source which is assembled directly into binary format). If you're assembler is generating an object file instead of a binary then you may need a linker script. This would depend on which assembler, boot loader and linker and how they are used.

Your problem may also be your boot loader (is the .data section loaded?), the data segment register contents (DS, ES), the GDT contents (correct bases?). Another possibility is the ORG you told the assembler (e.g. if CS base is 0x90000 you may have told the assembler to use ORG 0, so that if data segments have base = 0 data offsets are wrong).

Another problem you are likely to have is that most BIOS's have an EBDA (extended BIOS data area) that is below the video display memory. Depending on how big your kernel is it may overwrite the EBDA and/or the video display memory and/or the video BIOS. For example, if your kernel uses 96 Kb (.text + .data + .bss) you will overwrite the video display memory from 0xA0000 to 0xB0000. If the kernel is using a text video mode (which starts at 0xB8000) you might not notice this on the screen....


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Pulser

Re:Access Variables in Kernel

Post by Pulser »

Ok... I'm going for the ORG 0x7c00 approach in my boot loader. My GDT is:

Code: Select all

gdt:            ; Very start of our GDT
gdt_null:         ; Null Segment -> 4 Null Words
   dw 0         ; Null Word
   dw 0         ; Null Word
   dw 0         ; Null Word
   dw 0         ; Null Word
gdtCode:         ; Code Segment
   dw 0xFFFF      ; Limit -> 4GB
   dw 0x0000      ; Base Address -> 0 (Start of memory)
   db 0x00         ; Continue base address
   ; Access flag -> 0, Readable Segment -> 1, Conforming -> 0
   ; Code Segment -> 1, Code/Data Segment -> 1, Privelage level -> 00
   ; Present -> 1
   db 10011010b      ; Above flags
   ; Last bits of segment limit -> 1111, Ignored -> 0, Reserved -> 0,
   ; 32-bit code -> 1, Granularity -> 1, 
   db 11001111b      ; Above flags
   db 0x00         ; Remaining base address
gdtData:         ; Our data segment
   dw 0xFFFF      ; Limit -> 4GB
   dw 0x0000      ; Base Address -> 0 (Start of memory)
   db 0x00         ; Continue base address
   ; Accessed -> 0,  Writeable Segment -> 1, Expand -> 0 (down),
   ; Code Segment -> 0 (data), Code/Data Segment -> 1, Privelage -> 00
   ; Present -> 1
   db 10010010b      ; Above flags
   ; Last bits of segment limit -> 1111, Ignored -> 0, Reserved -> 0,
   ; 32-bit code -> 1, Granularity -> 1
   db 11001111b      ; Above Flags
   db 0x00         ; Remaining base address
gdtEnd:            ; End of our GDT

gdtDesc:         ; GDT Descriptor
   dw gdtEnd-gdt      ; Size of GDT in bytes
   dd gdt         ; GDT's memory address
I load my kernel to 0x90000 (ES -> 0x9000)
I disable interrupts...
Load my GDT
Enable protected mode, and far jump to 0x08:Pmode
Then:

Code: Select all

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp 0x90000 ; Jumps to the fully loaded kernel
And my kernel cant access its variables in the "[section .data]". Any hints would be very much appreciated. Thanks :)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Access Variables in Kernel

Post by Brendan »

Hi,
Pulser wrote: Ok... I'm going for the ORG 0x7c00 approach in my boot loader. My GDT is:

I load my kernel to 0x90000 (ES -> 0x9000)
This all looks correct, as long as you use "ORG 0x90000" for your kernel.

You didn't mention which assembler and how it's invoked. If you are using NASM (source code looks like NASM), then:
nasm -o kernel.bin -f binary source.asm
would work and doesn't require a linker script (or linker).

If this is the case, then I'm lost (unless you're using paging?) :)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply