Fighting with a GDT
Posted: Sat Mar 01, 2014 3:13 pm
Hi!
I've recently just started developing my own OS and currently I've just reached the dreaded protected mode stage. I've spent about a month reading up about this and planning a GDT, but today when it comes to it I just can't seem to jump to my code segment selector! Somehow every segment I try for the jump just doesn't work, and Boch's log output for various segments doesn't seem to match what's in my GDT (e.g. I say jump to segment ABC and it says "invalid TSS" when segment ABC isn't a TSS etc. etc.). I've checked that the GDT is being read from disk and set up correctly.
I've recently just started developing my own OS and currently I've just reached the dreaded protected mode stage. I've spent about a month reading up about this and planning a GDT, but today when it comes to it I just can't seem to jump to my code segment selector! Somehow every segment I try for the jump just doesn't work, and Boch's log output for various segments doesn't seem to match what's in my GDT (e.g. I say jump to segment ABC and it says "invalid TSS" when segment ABC isn't a TSS etc. etc.). I've checked that the GDT is being read from disk and set up correctly.
Code: Select all
;This is the bootloader for xxxOS.
;It loads the kernel file (consisting of a GDT, IDT and a set of interrupt handlers) and then tells it to initialise.
;Note that we don't actually need to set up a GDT/IDT: this is stored in the kernel file and loaded when we load the kernel.
entry start
start:
;The first thing we want here is a temporary usable stack.
;We'll use the memory where the kernel will later set up its data blocks.
mov ax, #0x0050
mov ss, ax
mov ax, #0x00FF
mov sp, ax
;This specifies the place where the kernel will be loaded.
mov ax, #0x1000
mov es, ax
;Set another segment to the video memory, as this will be needed later for status messages.
mov ax, #0xB800
mov fs, ax
;Display the start of the progress bar.
seg fs
mov [0], #0x41
seg fs
mov [1], #0x71
;896 sectors
;458752 bytes
mov ch, #1 ;First track number
mov dh, #0 ;First head number
readloop:
call readtrack
not dh
and dh, #1
cmp dh, #0
jnz readloop
;Increment the progress bar.
mov al, ch ;Prepare the character to display
add al, #0x41
mov bl, ch ;Calculate the video memory offset
mov bh, #0
rol bx, #1
seg fs
mov [bx], al ;Output the character...
add bx, #1
seg fs
mov [bx], #0x71 ;...and the attributes (blue on grey).
inc ch
cmp ch, #26 ;We're reading a total of 25 tracks starting from track 1
jnz readloop
;Enable A20.
;Load GDT and IDT registers.
mov ax, #0x1000
mov ds, ax
lgdt [0x0000]
mov ax, #0x2000
mov ds, ax
lidt [0x0000]
;Enter protected mode.
cli
mov eax, cr0
or al, #1
mov cr0, eax
;Initialise the kernel.
; hlt
; int 0xF0
jmp 0x0E:0
;We should never get down here, but just in case...
hlt
readtrack:
mov cl, #1
trackloop:
call readsector
inc cl
cmp cl, #19
jnz trackloop
ret
readsector:
mov bx, #0 ;Offset within extra segment for destination
mov dl, #0 ;Drive number
mov al, #1 ;Number of sectors to read
mov ah, #2 ;Function code (2 = read sectors from disk)
int 0x13
cmp ah, #0 ;Check for errors
jnz readerror
mov bx, es ;Adjust the destination pointer ready for next sector
add bx, #0x0020
mov es, bx
ret
readerror:
mov al, ah ;Prepare the character to display (represents error code)
add al, #0x30
mov bl, ch ;Calculate the video memory offset
mov bh, #0
rol bx, #1
seg fs
mov [bx], al ;Output the character...
add bx, #1
seg fs
mov [bx], #0x74 ;...and the attributes (red on grey).
hlt