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