Help me with PMODE!
Posted: Thu Apr 08, 2004 11:00 pm
Hi! I've started some time ago writing my operating system. I have this bootsector:
[BITS 16] ; We need 16-bit intructions for Real mode
[ORG 0x7C00] ; The BIOS loads the boot sector into memory location 0x7C00
mov ax,cs
mov ds,ax
mov es,ax
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
reset_drive:
mov ax,0
mov dl,0
int 13h
jc reset_drive
read: ; load kernel to 1000h
mov ax,1000h
mov es,ax
mov bx,0
mov ah,2
mov al,10; sectors ===========
mov ch,0 ; cylinder - 0
mov cl,2 ; first sect - 2
mov dh,0 ; head - 0
mov dl,0 ; drive - 0
int 13h ; read!
jc read
jmp 1000h:0000 ; start loaded code
times 510-($-$$) db 0 ; Fill up the file with zeros
dw 0AA55h ; Boot sector identifyer
And it works.
And I have some small kernel that starts protected mode, but it isn't working. What is wrong? Computer resets.
[BITS 16]
[ORG 0x1000]
cli ; Disable interrupts, we want to be alone
xor ax, ax
mov ds, ax ; Set DS-register to 0 - used by lgdt
lgdt [gdtr] ; Load the GDT descriptor
mov eax, cr0 ; Copy the contents of CR0 into EAX
or eax, 1 ; Set bit 0
mov cr0, eax ; Copy the contents of EAX into CR0
jmp CODE_SEL:clear_pipe ; Jump to code segment, offset clear_pipe
[BITS 32] ; We now need 32-bit instructions
clear_pipe:
mov ax, 10h ; Save data segment identifyer
mov ds, ax ; Move a valid data segment into the data segment register
mov ss, ax ; Move a valid data segment into the stack segment register
mov esp, 090000h ; Move the stack pointer to 090000h
mov byte [ds:0B8000h], 'P' ; Move the ASCII-code of 'P' into first video memory
mov byte [ds:0B8001h], 1Bh ; Assign a color code
hang:
jmp hang
gdtr:
lim dw gdt_end - gdt - 1 ; GDT limit
dd gdt ; (GDT base gets set above)
gdt:
NULL equ $-gdt ; Null Segment
dw 0 ; Limit 15:0
dw 0 ; Base 15:0
db 0 ; Base 23:16
db 0 ; Type
db 0 ; Limit 19:16, flags
db 0 ; Base 31:24
CODE_SEL equ $-gdt ; Code segment, read/execute, nonconforming
gdt1:
dw 0xFFFF ; Limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x9A ; Present, ring 0, code, non-conforming, readable
db 0xCF ; Page-granular, 32-bit
db 0
DATA_SEL equ $-gdt ; Data segment, read/write, expand down
gdt2:
dw 0xFFFF ; Limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x92 ; Present, ring 0, data, expand-up, writable
db 0xCF ; Page-granular, 32-bit
db 0
gdt_end:
[BITS 16] ; We need 16-bit intructions for Real mode
[ORG 0x7C00] ; The BIOS loads the boot sector into memory location 0x7C00
mov ax,cs
mov ds,ax
mov es,ax
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
reset_drive:
mov ax,0
mov dl,0
int 13h
jc reset_drive
read: ; load kernel to 1000h
mov ax,1000h
mov es,ax
mov bx,0
mov ah,2
mov al,10; sectors ===========
mov ch,0 ; cylinder - 0
mov cl,2 ; first sect - 2
mov dh,0 ; head - 0
mov dl,0 ; drive - 0
int 13h ; read!
jc read
jmp 1000h:0000 ; start loaded code
times 510-($-$$) db 0 ; Fill up the file with zeros
dw 0AA55h ; Boot sector identifyer
And it works.
And I have some small kernel that starts protected mode, but it isn't working. What is wrong? Computer resets.
[BITS 16]
[ORG 0x1000]
cli ; Disable interrupts, we want to be alone
xor ax, ax
mov ds, ax ; Set DS-register to 0 - used by lgdt
lgdt [gdtr] ; Load the GDT descriptor
mov eax, cr0 ; Copy the contents of CR0 into EAX
or eax, 1 ; Set bit 0
mov cr0, eax ; Copy the contents of EAX into CR0
jmp CODE_SEL:clear_pipe ; Jump to code segment, offset clear_pipe
[BITS 32] ; We now need 32-bit instructions
clear_pipe:
mov ax, 10h ; Save data segment identifyer
mov ds, ax ; Move a valid data segment into the data segment register
mov ss, ax ; Move a valid data segment into the stack segment register
mov esp, 090000h ; Move the stack pointer to 090000h
mov byte [ds:0B8000h], 'P' ; Move the ASCII-code of 'P' into first video memory
mov byte [ds:0B8001h], 1Bh ; Assign a color code
hang:
jmp hang
gdtr:
lim dw gdt_end - gdt - 1 ; GDT limit
dd gdt ; (GDT base gets set above)
gdt:
NULL equ $-gdt ; Null Segment
dw 0 ; Limit 15:0
dw 0 ; Base 15:0
db 0 ; Base 23:16
db 0 ; Type
db 0 ; Limit 19:16, flags
db 0 ; Base 31:24
CODE_SEL equ $-gdt ; Code segment, read/execute, nonconforming
gdt1:
dw 0xFFFF ; Limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x9A ; Present, ring 0, code, non-conforming, readable
db 0xCF ; Page-granular, 32-bit
db 0
DATA_SEL equ $-gdt ; Data segment, read/write, expand down
gdt2:
dw 0xFFFF ; Limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x92 ; Present, ring 0, data, expand-up, writable
db 0xCF ; Page-granular, 32-bit
db 0
gdt_end: