I don't have a kernel yet! Sorry. I have only been able to get into pmode. What seems to be happening is that when I remove the lines after setting the cr0 bit, ie:
mov ax, 0x10
mov ds, ax
My os doesn't reboot. It just hangs at my "jmp $"
Yet, when I add that line back in, It reboots.
So it's a bootsector ?
In that case your code should be loaded to 0x7c00 by the BIOS.
First make sure that your bootsector is linked correctly:
Code: Select all
(first line in your file)
org 0x7C00
bits 16
enable_A20:
...
Also remember that there has to be a magic number at the end of your bootsector.
Code: Select all
(last line of code/data)
times 510-($-$$) db 0
dw 0xAA55
The first line will fill the remaining sector (except the very last 2 bytes) with zeroes. These 2 bytes will then be used for the signature in the second line.
$ = current address (orgin + offset, for example 0x7c00+enable_A20)
$$ = origin of the file (org directive, 0x7c00)
Are you talking about this:
...
Could I just then use something like this for the gdt limit:
limit:
dw (3*4)-1 ;(3 descripters*4 words)-1
No - I was actually talking about the 'gdt base address'. The limit is a relative value, so even if your offset is wrong there shouldn't be any problems.
The labels in NASM consist of (code origin)+(offset in the code). The origin is set using the org-directive:
Code: Select all
org 0x7c00
label1:
; label1 = origin + offset1 -> 0x7c00 + 0
<lots of code1>
label2:
; label2 = origin + offset2 -> 0x7c00 + sizeof(lots of code1)
<lots of code2>
label3:
; label3 = origin + offset3 -> 0x7c00 + sizeof(lots of code1+2)
<lots of code3>
data1 dd label3-label1
; data1 = (origin + offset3) - (origin + offset1) = offset3 - offset1
Anyway, since you have a bootsector rather than a kernel the 'gdt base address' isn't a problem either (just leave it as is).
The reason your code wouldn't work in a kernel is that it must be executed within the first 64k of memory and most/all kernels are loaded beyond the 1MB mark. If it is executed at a higher address, the (real-mode) code-segment can't be zero and you have to colculate the physical address at run-time as I've showed you.
Yet, when I add that line back in, It reboots.
Outcommenting this line won't really help because you aren't in pmode before you've reloaded all segment registers. And don't forget to set up the stack:
Code: Select all
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x200000 ; 2MB
Now everything is ready to jump to pmode...
Code: Select all
jmp dword 0x08:pmode
bits 32
pmode:
jmp $
regards,
gaf