flat assembler
Message board for the users of flat assembler.

flat assembler > OS Construction > Pmode pipeline flush problem!

Author
Thread Post new topic Reply to topic
Mac2004



Joined: 15 Dec 2003
Posts: 313
Hello !

I have got a following problem wth my pm code. This source is a secondary file that is loaded into memory at location 0x1000. Loading works fine, but when the pipeline jmp is reached my computer crashes.

I would guess that the problem might be in incorrect jmp instruction, but is there something else?? Might be a Fasm specific problem??

This same code works fine when it is placed inside a bootblock and pmode is starrted from there.

regards
Mac2004


;======================================================
;Protected mode secondary file. This code is loaded
;by bootf_rm-bootloader into memory location 0x1000.
;
;This program is coded with Fasm.
;
;Reference: Daniels NASM Bootstrap Tutorial
;======================================================

use16 ; We now need 16-bit instructions

jmp start

;----------------------------------------------
; The GDT descriptor
gdt_desc:

dw gdt_end - gdt - 1 ; Limit (size)
dd gdt ; Address of the GDT

;----------------------------------------------

;========================
;Main programm starts
;========================

start:
mov ax, 1000h ;Update segment registers
mov ds, ax
mov es, ax

;print that we're alive!
;-----------------------

mov si, switching_msg ; Print a message
call RM_putstr

mov ah,0
int 16h


;init PM-code
;-----------------------

cli
xor ax, ax
mov ds, ax ;Set DS-register to 0 - used by lgdt

lgdt [gdt_desc] ;Load the GDT descriptor

;; save real-mode CS in BP
mov bp,cs

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


;=======================================
;this following jump makes the computer
to tripple fault(=reset)
;=======================================

jmp gdt_code:start_pm ; Jump to code segment, offset start_pm


;==============================================================================
;32 bit code starts from here

USE32 ; We now need 32-bit instructions

start_pm:

mov ax, gdt_data ; 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
mov byte [ds:0B8002h], 'M' ; Move the ASCII-code of 'M' into first video memory
mov byte [ds:0B8003h], 1Bh ; Assign a color code
mov byte [ds:0B8004h], '!' ; Move the ASCII-code of '!' into first video memory
mov byte [ds:0B8005h], 1Bh ; Assign a color code

hang:
jmp hang ; Loop, self-jump

;==============================================================================
;GLOBAL DESCRIPTOR TABLE(GDT)
;
;Every descriptor contains a label that counts it's address offset from 0 to ffffh.
;The value is the segment value and must must be divisible by 8 (dec.). This counted
;label allows us to use it as segment address without caring about its true numerical
;value. (Miscorrect values often mean tripple-fault and rebooting the PC.)


gdt: ; Address for the GDT
;gdt_null: ; Null Segment
dd 0
dd 0

;gdt_code: ; Code segment, read/execute, nonconforming
gdt_code = $-gdt
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0

;gdt_data: ; Data segment, read/write, expand down
gdt_data = $-gdt
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
;User Code segment, read/execute, nonconforming
gdt_user_code = $-gdt ;NOTE: actual values are NOT correct for user code selector!!!!!
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0

;gdt_data: ; Data segment, read/write, expand down
gdt_data2 = $-gdt
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0

gdt_end: ; Used to calculate the size of the GDT


;==============================================================================
;16 bit procedures

use16 ; We now need 16-bit instructions

;***************************************************
; RM_putstr: Print a 0-terminated string (SI=pointer to string)
;
; Input: SI=pointer to string
;
; Output: --
;***************************************************

RM_putstr:
lodsb
or al,al
jz .putstrd
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp RM_putstr
.putstrd:
retn


switching_msg db '2-stage loaded!!',13,10,0
Post 23 Mar 2004, 22:05
View user's profile Send private message Reply with quote
Gomer73



Joined: 29 Nov 2003
Posts: 151
Makes sense that the computer would reboot, as the GDT is probably loaded with giberish.
If you see your message displayed then the GDT is wrong.
The message is at an offset from a 0x1000 segment.
The GDT relies on the segment being at a 0 segment(GDT address must be linear address from base 0).

The following two lines should make your code work(if your protected mode segments are based at 0-I didn't have time to look up the GDT parameters):


dd gdt + 0x10000 ; Address of the GDT

lgdt [es:gdt_desc] ;Load the GDT descriptor

I may have trouble explaining it in words, but the code should explain what I mean more easily.
Post 26 Mar 2004, 00:52
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 313
Thanx!

The very same code was fully workable when I previously placed it inside a bootblock code.

I will have a look at your answer and see what happens. Smile
Post 31 Mar 2004, 07:56
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.