iansjack wrote: ↑Sun Mar 02, 2025 2:35 pm
Without seeing your code it’s not easy to guess what you are doing wrong. Do you have an on-line repository?
Unfortunately, I don't.
After a bit more poking around with the debugger I have confirmed that my stack is in the place where I expect it to be. It almost seems as though my .data section has been moved as well. So it's not so much a data corruption problem as it is the data isn't where my C code expects to find it.
May some code snippets will help.
GDT definition
Code: Select all
.align 8
gdt:
.long 0 # system reserved entry
.long 0
gdt_code: # limit 0 - ffffffff
.word 0xffff # segment limit 0-15
.word 0x0 # base 0-15
.byte 0x0 # base 15-23
.byte 0x9a # present, priv 0, code segment, readable
.byte 0xcf # 4k blocks, 32-bit, limit 16-19
.byte 0 # base 24-31
gdt_data: # limit 0 - ffffffff
.word 0xffff # segment limit 0-15
.word 0x0 # base 0-15
.byte 0x0 # base 15-23
.byte 0x92 # present, priv 0, data segment, writable
.byte 0xcf # 4k blocks, 32-bit, limit 16-19
.byte 0 # base 24-31
gdt_stack: # limit 3e00 - 07dff
.word 0x3fff # segment limit 0-15
.word 0x3e00 # base 0-15
.byte 0x0 # base 15-23
.byte 0x92 # present, priv 0, data segment, writable
.byte 0x40 # byte granularity, 32-bit, limit 16-19
.byte 0 # base 24-31
gdt_end:
.equ gdt_len, gdt_end - gdt
.equ CODE_SEG, gdt_code - gdt
.equ DATA_SEG, gdt_data - gdt
.equ STACK_SEG, gdt_stack - gdt
Set up 32 bit mode
Code: Select all
# Copy initial GDT to low memory
cld # set movs to increment
movw $gdt,%si # move from our copy of GDT
movw $GDT,%di # to the one in low memory
movw $gdt_len,%cx # for the length of our copy
rep
movsb
# Enable 32-bit protected mode
cli # disable interrupts until we are ready
movw $GDT_LEN,GDT_REG # init the GDT register with the length
movl $GDT,GDT_REG+2 # & the address
lgdt GDT_REG # load the global descriptor table
movl %cr0,%eax # set protected mode
orl $0x01,%eax
movl %eax,%cr0
jmp $CODE_SEG,$start # force CS to use entry from GDT
.code32
# From this point on, we are in 32-bit protected mode.
start:
movw $DATA_SEG,%ax # set data segment registers
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
# Set up a stack
#
# GDT stack segment is configured to support a 16K kernel
# stack occupying 0x3e00 - 0x7dff
movw $STACK_SEG,%ax
movw %ax,%ss
movl $0x3ff0,%esp # set bottom of stack to end of boot area
Using the debugger I have verified that DS contains 0x10 and SS contains 0x18. Changing the offset on the segment description that I am using for the stack causes everything to start working again. Hmmmm!