more GDT trouble.....
Posted: Tue Aug 05, 2003 11:00 pm
First off I want to thank everyone who has been helping me with this. But Unfortunately I still haven't been able to use the GDT correctly. However since I'm new to this it could very well be that I have done something else wrong so I included the code for my entire bootsector. So if anyone has nothing better to do than debug someone's code over the internet that they have never met Please feel free to look over this and let me know if there is anything horribly wrong.
FYI currently a small kernel that occupies the second sector of the boot disk is loaded into memory. I have taken out the instruction that jumps to it because....well...I can't use my pmode descriptors to do the jump. In regards to everyone's suggestions I have tried all of them and whatever the method in the code right now is just the remnants of the last attempt to load a valid address for the GDT. Thank you to all and let the fun begin
;; pmboot.asm
;; skeleton bootloader
%define KERN_LOAD 0x500
%define STACK 0xFF00 ; Beginning of the Stack
%define STACK_P 0xFFFE ; Where the stack is (ended)
%define BASE_SEG 0x9000
%define MEM_START 0x0
org 07c00h ; start address 0000:07c00h physical
nop
skipdata:
bits 16
mov ax, 0x0600 ; BIOS-function clear/scroll window
mov cx, 0x0 ; define window to be cleared from
mov dx, 0x174F ; to 23, 79
mov bh, 0 ; fillcolor = 0
int 10h ; BIOS -clear screen- go!
mov ax, 0xB800
mov gs, ax ; point gs to video memory
mov word [gs:0],0x641 ; display brown 'A'
mov word [gs:2],0x642 ; display brown 'B'
mov ax, BASE_SEG ; set up stack
mov ss, ax ; Stack segment
mov sp, STACK_P ; and of course the stack pointer-end of stack
mov bx, KERN_LOAD ; This is where I specify where to place the
mov ax, MEM_START ; kernel I'd like it to go to 0x600 physical
mov es, ax ; but I think its obvious that I'm having some
; real mode addressing issues
read: mov ah, 2 ; function name (2)
mov al, 1 ; number of sectors to read
mov ch, 0 ; track number
mov cl, 2 ; sector number = 2 (this is the kernel)
mov dh, 0 ; head number
mov dl, 0 ; drive number 0 = floppy (?)
int 13h ; read the kernel into memory
push cs
pop ds ; load ds with cs
xor eax,eax ; This is the method that Adek and Dr. 128
mov ax,cs ; suggested but I've tried all of the others
shr eax,4 ; that people hav posted and unfortunately
add eax,gdt ; have not had that much luck with any of them
mov dword[gdtr+2],eax ; But thanks again for the help from everyone!
lgdt [ds:gdtr] ; load gdt reg
mov word [gs:4],0x643 ; display brown 'C'
;; Move into **P_MODE**
mov eax, cr0 ; read control reg
or al, 1 ; set PM bit
mov cr0, eax ; transfer it to control port
mov word [gs:6],0x644 ; display brown 'D'
; This is the last character that prints
jmp CODE_SEL:pmode ; into pmode (32-bit mode)
; I think this is where the trouble is
pmode:
[BITS 32]
;; set the segments up
mov word [gs:8],0x645 ; display brown 'E'
mov ax, DATA_SEL ; set data selector
mov ds, ax ; for the data segment
mov es, ax ; extra segment
mov fs, ax
mov gs, ax
mov ss, ax ; stack segment
mov ax, VIDEO_SEL
mov gs, ax ; point gs to video memory
mov word [gs:10],0x741 ; display white 'a'
spin:
jmp spin ; loop
[bits 16]
gdtr
dw gdt_end-gdt-1 ; length of GDT
dd gdt ; linear physical address of the GDT
gdt:
;null descriptor ; 0h = 000b
; null descriptor
dw 0
dw 0
db 0
db 0
db 0
db 0
VIDEO_SEL equ $-gdt ; 18h = 11000b
dw 0ffffh ; limit 80*25*2-1
dw 0 ; base 0xB8000
db 0
db 092h
db 0cfh ; present, ring 0, data, expand up, writable
db 0 ; byte-granular, 16-bit
code_gdt:
CODE_SEL equ $-gdt ; 8h = 1000b
; code descriptor 4 GB flat segment starting 0000:0000h
dw 0ffffh ; limit 4 GB
dw 0 ; Base 0000:0000h
db 0
db 09ah
db 0cfh
db 0h
data_gdt:
DATA_SEL equ $-gdt ; =10h = 10000b
; data descriptor 4 GB flat segment starting 0000:0000h
dw 0ffffh ; limit 4 GB
dw 0h ; Base 0000:0000h
db 0h
db 092h
db 0cfh
db 0h
gdt_end:
;; equates
lf equ 10
cr equ 13
times 510-($-$$) db 0
dw 0xaa55
FYI currently a small kernel that occupies the second sector of the boot disk is loaded into memory. I have taken out the instruction that jumps to it because....well...I can't use my pmode descriptors to do the jump. In regards to everyone's suggestions I have tried all of them and whatever the method in the code right now is just the remnants of the last attempt to load a valid address for the GDT. Thank you to all and let the fun begin
;; pmboot.asm
;; skeleton bootloader
%define KERN_LOAD 0x500
%define STACK 0xFF00 ; Beginning of the Stack
%define STACK_P 0xFFFE ; Where the stack is (ended)
%define BASE_SEG 0x9000
%define MEM_START 0x0
org 07c00h ; start address 0000:07c00h physical
nop
skipdata:
bits 16
mov ax, 0x0600 ; BIOS-function clear/scroll window
mov cx, 0x0 ; define window to be cleared from
mov dx, 0x174F ; to 23, 79
mov bh, 0 ; fillcolor = 0
int 10h ; BIOS -clear screen- go!
mov ax, 0xB800
mov gs, ax ; point gs to video memory
mov word [gs:0],0x641 ; display brown 'A'
mov word [gs:2],0x642 ; display brown 'B'
mov ax, BASE_SEG ; set up stack
mov ss, ax ; Stack segment
mov sp, STACK_P ; and of course the stack pointer-end of stack
mov bx, KERN_LOAD ; This is where I specify where to place the
mov ax, MEM_START ; kernel I'd like it to go to 0x600 physical
mov es, ax ; but I think its obvious that I'm having some
; real mode addressing issues
read: mov ah, 2 ; function name (2)
mov al, 1 ; number of sectors to read
mov ch, 0 ; track number
mov cl, 2 ; sector number = 2 (this is the kernel)
mov dh, 0 ; head number
mov dl, 0 ; drive number 0 = floppy (?)
int 13h ; read the kernel into memory
push cs
pop ds ; load ds with cs
xor eax,eax ; This is the method that Adek and Dr. 128
mov ax,cs ; suggested but I've tried all of the others
shr eax,4 ; that people hav posted and unfortunately
add eax,gdt ; have not had that much luck with any of them
mov dword[gdtr+2],eax ; But thanks again for the help from everyone!
lgdt [ds:gdtr] ; load gdt reg
mov word [gs:4],0x643 ; display brown 'C'
;; Move into **P_MODE**
mov eax, cr0 ; read control reg
or al, 1 ; set PM bit
mov cr0, eax ; transfer it to control port
mov word [gs:6],0x644 ; display brown 'D'
; This is the last character that prints
jmp CODE_SEL:pmode ; into pmode (32-bit mode)
; I think this is where the trouble is
pmode:
[BITS 32]
;; set the segments up
mov word [gs:8],0x645 ; display brown 'E'
mov ax, DATA_SEL ; set data selector
mov ds, ax ; for the data segment
mov es, ax ; extra segment
mov fs, ax
mov gs, ax
mov ss, ax ; stack segment
mov ax, VIDEO_SEL
mov gs, ax ; point gs to video memory
mov word [gs:10],0x741 ; display white 'a'
spin:
jmp spin ; loop
[bits 16]
gdtr
dw gdt_end-gdt-1 ; length of GDT
dd gdt ; linear physical address of the GDT
gdt:
;null descriptor ; 0h = 000b
; null descriptor
dw 0
dw 0
db 0
db 0
db 0
db 0
VIDEO_SEL equ $-gdt ; 18h = 11000b
dw 0ffffh ; limit 80*25*2-1
dw 0 ; base 0xB8000
db 0
db 092h
db 0cfh ; present, ring 0, data, expand up, writable
db 0 ; byte-granular, 16-bit
code_gdt:
CODE_SEL equ $-gdt ; 8h = 1000b
; code descriptor 4 GB flat segment starting 0000:0000h
dw 0ffffh ; limit 4 GB
dw 0 ; Base 0000:0000h
db 0
db 09ah
db 0cfh
db 0h
data_gdt:
DATA_SEL equ $-gdt ; =10h = 10000b
; data descriptor 4 GB flat segment starting 0000:0000h
dw 0ffffh ; limit 4 GB
dw 0h ; Base 0000:0000h
db 0h
db 092h
db 0cfh
db 0h
gdt_end:
;; equates
lf equ 10
cr equ 13
times 510-($-$$) db 0
dw 0xaa55