Hi again,
Nobody seems to want to touch my last post so I will just include the code here
and hopefully someone can help, I am new to OS programming and I have
been reading the theory and trying for days to get this boot code to work, I dont
understand why it doesn't work however it never triple faults my cpu so I dont know that it is not working, it just wont print the char to video memory so I can see that it has worked, anyway here is the code
can someone please have a look and help me out.
This code is written for NASM.
Thanks.
Here is the code:
[BITS 16]
[ORG 0x07C0]
jmp short PlayOSBoot
; ===========================================================
; The GDTR Limit and Base
gdtr
dw 0xFFFF
dd 0
; ===========================================================
; The GDT Setup Entries
gdt_start
; Null Segment Descriptor, 0x00
dd 0
dd 0
; Code Segment Descriptor, 0x08
db 11111111b ; 4GB Limit
db 11111111b ; 4GB limit
db 00000000b ; Base 0
db 00000000b ; Base 0
db 00000000b ; Base 0
db 10011010b ; Present : Ring 0 : Code\Exec : Non-Conforming : Readable
db 11001111b ; 4KB Granularity : 32Bit : 4GB Limit
db 00000000b ; Base 0
; Data Segment Descriptor, 0x10
db 11111111b ; 4GB Limit
db 11111111b ; 4GB limit
db 00000000b ; Base 0
db 00000000b ; Base 0
db 00000000b ; Base 0
db 10010010b ; Present : Ring 0 : Data : Expand Up : Writable
db 11001111b ; 4KB Granularity : 32Bit : 4GB Limit
db 00000000b ; Base 0
gdt_end
; ===========================================================
; BootLoader Starting Position
PlayOSBoot:
; ====================================
; Move this code out of the way
cld
mov ax, 0x4000
mov es, ax
xor di, di
xor si, si
mov cx, 0x0100
rep movsw
; ====================================
; Jump to the New Location
jmp 0x4000:NewLocation
NewLocation:
; ====================================
; Move the GDT entries into position
cld
xor ax, ax
mov es, ax
mov ax, 0x4000
mov ds, ax
xor di, di
mov si, gdt_start
mov cx, gdt_end - gdt_start - 1
rep movsb
; ====================================
; Enable the A20 Gate
call Empty_8042
mov al, 0xD1
out 0x64, al
call Empty_8042
mov al, 0xDF
out 0x60, al
call Empty_8042
jmp A20_GateDone
Empty_8042:
mov al, 0xD0
in al, 0x64
test al, 2
jnz Empty_8042
ret
A20_GateDone:
; ====================================
; Disable Interrupts
cli
; ====================================
; Load the GDTR
lgdt [gdtr]
; ====================================
; Set PM Bit
mov eax, cr0
or eax, 1
mov cr0, eax
; ====================================
; Jump into PMode Code
jmp dword 0x08:0x40000 + EnterPMode
EnterPMode:
; ====================================
; Set Data and Stack Segments
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; ====================================
; Is this actually going to put something into video memory
mov ecx, 0xB8000
mov word [ecx], 0x1E41
; Loop forever
HaltPlayOS:
jmp short HaltPlayOS
times 510-($-$$) db 0
PlayOS_Signature dw 0xAA55
Still Having PMode Trouble
Re:Still Having PMode Trouble
I have seen lot of things bad.
1- the ORG 0x07c0, you can use that org, but it will be more dificult for other things. i recomend you use ORG 0X7C00 or if you prefer ORG 0.
2- you use DS and still didnt initialize it. You doesnt know where is it pointing to when your code starts. in diferent computers may have diferent values, so best thing you should do is initialize it, if you use ORG 0X7C00 initialize it with 0(ds=0) if you use ORG 0; initialize it with 0x07C0. You must know that the offsets change if you change the ORG.
3-
; ====================================
; Move this code out of the way
cld
mov ax, 0x4000
mov es, ax
xor di, di
xor si, si
mov cx, 0x0100
rep movsw
; ====================================
; Jump to the New Location
in this jump you go to 0x4000:NewLocation, but NewLocation is with base 0x07c0 (what you put)
so It will jump to another diferent place that you doesnt know
jmp 0x4000:NewLocation
NewLocation:
; ====================================
; Move the GDT entries into position
Now you copy the GDT into the real mode IDT (at 0:0)
You may think that you will not need the realmode IDT but, that may change.
cld
xor ax, ax
mov es, ax
mov ax, 0x4000
mov ds, ax
xor di, di
at this point SI=OFFSET GDT_START, and because of the ORG 0x07C0 it will be 0x07C0 bytes more that what you wants.
mov si, gdt_start
mov cx, gdt_end - gdt_start - 1
rep movsb
4-
; ====================================
; Load the GDTR
again, the pointer to gdtr is wrong is 0x07c0 bytes more of what you wants.
lgdt [gdtr]
5-
; ====================================
; Jump into PMode Code
You cannot do this kind of jump, because the offset is more than 16 bits. You already have set the PE bit, but the CS segment isnt loaded to use 32 bit instructions, so you are limited to 16 bits offsets.
jmp dword 0x08:0x40000 + EnterPMode
You can read my boot sector, it is in one thread called something like "first i cant link, now i cant enter pmode", it is not very well comented, and i use lot of things to make code smaller, but it may help you.
1- the ORG 0x07c0, you can use that org, but it will be more dificult for other things. i recomend you use ORG 0X7C00 or if you prefer ORG 0.
2- you use DS and still didnt initialize it. You doesnt know where is it pointing to when your code starts. in diferent computers may have diferent values, so best thing you should do is initialize it, if you use ORG 0X7C00 initialize it with 0(ds=0) if you use ORG 0; initialize it with 0x07C0. You must know that the offsets change if you change the ORG.
3-
; ====================================
; Move this code out of the way
cld
mov ax, 0x4000
mov es, ax
xor di, di
xor si, si
mov cx, 0x0100
rep movsw
; ====================================
; Jump to the New Location
in this jump you go to 0x4000:NewLocation, but NewLocation is with base 0x07c0 (what you put)
so It will jump to another diferent place that you doesnt know
jmp 0x4000:NewLocation
NewLocation:
; ====================================
; Move the GDT entries into position
Now you copy the GDT into the real mode IDT (at 0:0)
You may think that you will not need the realmode IDT but, that may change.
cld
xor ax, ax
mov es, ax
mov ax, 0x4000
mov ds, ax
xor di, di
at this point SI=OFFSET GDT_START, and because of the ORG 0x07C0 it will be 0x07C0 bytes more that what you wants.
mov si, gdt_start
mov cx, gdt_end - gdt_start - 1
rep movsb
4-
; ====================================
; Load the GDTR
again, the pointer to gdtr is wrong is 0x07c0 bytes more of what you wants.
lgdt [gdtr]
5-
; ====================================
; Jump into PMode Code
You cannot do this kind of jump, because the offset is more than 16 bits. You already have set the PE bit, but the CS segment isnt loaded to use 32 bit instructions, so you are limited to 16 bits offsets.
jmp dword 0x08:0x40000 + EnterPMode
You can read my boot sector, it is in one thread called something like "first i cant link, now i cant enter pmode", it is not very well comented, and i use lot of things to make code smaller, but it may help you.