flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Jump to PMode Problem (don't you just love alliteration :P)

Author
Thread Post new topic Reply to topic
Mota



Joined: 29 Dec 2004
Posts: 22
Mota 10 Feb 2005, 01:29
I'm using Bochs to help me with the OS Construction business because I haven't got a floppy drive. I have decided to try with 10 meg hardrive (on Bochs of course).

I designed the perfect filesystem for my OS, made a bootloader that runs it as far as I need it to. It works well, and loads a secondary loader (sounds sketchy, but that's the best way of doing it atm)

Once I began working on my secondary loader, I realised I needed to be able to reference memory in 32-bits before reaching my secondary loader (I'll just call it the loader). On my previous, less succesful attempt at a simple OS, I used paging, no segmentation, and it didnt work well. I was able to run 16-bit code perfectly, but not 32-bit code. Things like ret didnt work at all. Sad

This time, I decided to go for segmentation and paging, but only setting paging up in my loader, and segmentation before passing control to the loader.

Okay, so I load the GDT descriptor and try to jump to 0x08:FLUSH (to set CS to the appropriate segment. FLUSH is just a label following the jmp command)

But when I do this, bochs outputs an error to the log file, generates an exception (which is obviously unhandled), and resets.

The log file dump is as shown here:

Quote:

e-00007d9b-00004793670-[CPU ] jump_protected: gate type 0 unsupported
e-00007d96-00004793670-[CPU ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting


The code is below. My problem is I obviously want to make the jump, and cant because of the error/exception. The documentation and comments are a little off. they talk about loading a kernel, when it's really the loader.

Anyway , here's the code:

Code:
; Name     : Bootloader
; Author   : Francisco Mota
; Goals    : Set Segement Registers and 16-bit Stack
;            Load Disk Table
;            Load File Table
;            Traverse File Table
;            Load Kernel
;            Execute Kernel

; MACROS
include 'macros.inc'

; Start labels at 0x7C00, Generate 16-bit Code
org 0x7C00
use16

label drive byte at 0x1000

; Task 1: Setup Segment Registers and 16-bit Stack
mov [drive],dl

xor ax,ax ; Set ax to 0

mov ds,ax ; Set ds to 0
mov es,ax ; Set es to 0
mov fs,ax ; Set es to 0

mov ss,ax ; Set ss to 0
mov sp,0xFFFF  ; Set stack to point to 0xFFFF

mov ax,0xB800 ; Set ax to B800h
mov gs,ax ; Set gs to B800h


jmp 0:init         ; Clear CS
init:



; Task 2: Load Disk Table to 0x1001
lfd16 [drive],0,0,2,1,100h,1


; Task 3: Load File Table to 0x1201
lfd16 [drive],[drive+5],[drive+6],[drive+7],[drive+8],100h,201h


; Task 4: Traverse File Table



mov si,1201h

; Currently doesnt check for data continuation...
check_nodes:

push si

lodsw
mov [size_inf],ax


cmp ax,0x1802
je error

and ah,0x18
jz .cont

cmp ah,0x10
je .nsskip

pop si
mov ax, [size_inf]
xor ah, ah
add si, ax
jmp check_nodes

.nsskip:

lodsd
pop si
add si, ax
jmp check_nodes

.cont:

lodsd
mov dword [track], eax
lodsw
mov [offset],ax
lodsd
mov [kernel_size],eax




lodsd
cmp eax,"load"
jne .next

lodsw
cmp ax,'er'
jne .next

lodsb
or al, al
jne .next


jmp continue

.next:


pop si             ; Try next node
mov ax, [size_inf]
xor ah, ah
add si, ax
jmp check_nodes


error:
      printchar 'E'
jmp $



continue:

; Task 5: Load Kernel to 0x10000

    mov cx,1000h
    xor dx,dx
    mov ax,[offset]
    mov bx,10h
    div bx
    sub cx, ax

    lfd16 [drive],[track],[head],[sector],[nsects],cx,dx

; Task 5b: Continue Traversing Table until a non-data continuation node comes up.

    pop si             ; Move on to next node
    mov ax, [size_inf]
    xor ah, ah
    add si, ax

    xor cx, cx

    .get_node:

    push si

    lodsw
    mov [size_inf],ax

    cmp ax,080Ah
    je .next
    jmp .done

    .next:

    add cx,word [kernel_size]

    lodsd
    mov dword [track],eax
    lodsd
    mov [kernel_size],eax

    lfd16 [drive],[track],[head],[sector],[nsects],1000h,cx

    pop si             ; Move on to next node
    mov ax, [size_inf]
    xor ah, ah
    add si, ax
    jmp .get_node

    .done:


; Task 6 : Enter PMODE

   lgdt [GDT.DESC]

   mov eax,cr0
   or eax,1
   mov cr0,eax

;   mov ax,08h
;   mov cs,ax
   ;jmp $
   jmp 0x08:FLUSH


   use32
   FLUSH:                   ; This is where I wanna get to, and can't.
                      ;  jmp $    ; Uncomment this for debugging

; Task 7: Jump to Kernel
    mov ax,CODESEL
    mov ds,ax
    mov ss,ax
    mov esp,0x9FFFF

    jmp $
    jmp 0x8:0x1000




; Variables:
; Node info
size_inf dw 0
track db 0
head db 0
sector db 0
nsects db 0
offset dw 0
kernel_size dd 0


GDT:
.NULL:
dd 0
dd 0


CODESEL = $-GDT
dd 0FFFFh
dw  0000h
db  00h
db  10011110b
db  11001111b
db  0

DATASEL = $-GDT
dd 0FFFFh
dw  0000h
db  00h
db  10010010b
db  11001111b
db  0
.end:

.DESC:
 .dsize dw GDT.end - GDT -1
 .dbase dd GDT

; Fill up to 510 bytes, leaving space for the signature.
times (510 - ($-0x7C00)) db 0
; Boot Signature
dw 0xAA55
    


Thanks in advance for any possible help and advice, I would really like advice Razz

THanks anyway
Post 10 Feb 2005, 01:29
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 10 Feb 2005, 12:33
PMode Problem, precisely! Alliteration is fun, but round sounds of assonance are better. (Oh, that stinks...)

As for your problem...I'll have to play with it at home this evening.

A quick glance at your code doesn't reveal anything that is blaring at me, but I'm not an expert at this either.
Post 10 Feb 2005, 12:33
View user's profile Send private message Reply with quote
Mota



Joined: 29 Dec 2004
Posts: 22
Mota 10 Feb 2005, 14:11
Thanks Smile

I myself have found one error, but it's got nothing to do with PMode, just with loading the loader. Solving the error doesnt solve the problem.
Post 10 Feb 2005, 14:11
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 11 Feb 2005, 08:45
Hmm.. you will need a "cli" before going into pmode or else the adventure will end rather quickly.. Wink
and a zero is missing from your jumo to the kernel, it should be "jmp 0x8:0x10000"..

/ Christoffer
Post 11 Feb 2005, 08:45
View user's profile Send private message Reply with quote
Mota



Joined: 29 Dec 2004
Posts: 22
Mota 11 Feb 2005, 13:32
cool, thanks or the help.

I had already solved the problem by downloading working PMode code, but I didn't know what was wrong. Thanks for clearing it up.

Anyways, there's this other code which isn't working well. It's supposed to set all the page table and the page table directory. It isn't working so I used my old paging code and it works... why?

Here's the code:

Code:
; okay, allow pages up to 0x5FFFFF
; which is where the page directory
; and tables are going to be set
; eax = current address
; ecx = outer loop variable
; ebx = inner loop variable
; edx = current write address

paging:
; This code isn't working and is useless atm, I'll fix it once I figure out what's wrong with it
xor eax,eax
xor ecx,ecx
mov edx,0x102000

.outer_loop:                         ; Outer Loop

    cmp ecx, 1024                    ; Check if ecx is out of bounds
    jge .end_outer_loop              ;   if so, finish the loop.

    mov dword [ecx*4+0x101000],edx   ; Write page table address
    or dword [ecx*4+0x101000],3      ; or it with 0x303 (supervisor,read/write,pressent)

    xor ebx,ebx                      ; Reset ebx

    .inner_loop:                     ; Inner Loop

        cmp ebx, 1024                ; Check if ecx is out of bounds
        jge .end_inner_loop          ;   if so, finish the loop.

        mov dword [edx],eax          ; Write page physical address

        cmp eax,0x600000             ; Check if eax is over 0x600000
        jge .inner_loop_next         ;   if so, skip makeing page present

        or dword [edx],0x201         ;

        .inner_loop_next:

        or dword [edx],0x402

        inc ebx
        add edx, 4
        add eax, 4096

    .end_inner_loop:

    inc ecx

.end_outer_loop:

mov eax, 0x101000
mov cr3, eax

mov eax,cr0
or eax,0x80000000
mov cr0,eax
    


All the segments are set accordingly (cs to 0x8, the rest to 0x10)

The outer loop writes to the page table directory, and the inner loop writes to the page tables.

(Even though this is a new problem, there would be no point making a new thread, as this is also a bit to do with PMode....)

Thanks in advance again Razz


EDIT: Naaa forget it, I forgot to jmp to the loop starts .. daft me.
Post 11 Feb 2005, 13:32
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.