reboot when jumping to kernel

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Invisible Tape

reboot when jumping to kernel

Post by Invisible Tape »

Alright, when i try my kernel out in bochs, it works fine. When i try it on a real pc, it just reboots. I've found it does this at the instruction: jmp CODESEL:0x100000. This is in my bootsector, after i've enabled the a20, loaded my kernel to 0x100000, set up a gdt and entered pmode. I don't what could be going wrong as my bootloader worked before, and i've tried putting a cli and hlt at the beginning of my kernel.   Any help is appreciated.
AR

Re:reboot when jumping to kernel

Post by AR »

If you didn't alter the GDT without testing it in Bochs, are you sure A20 is enabled, are you testing it to make sure? Are you sure the Kernel in the correct place on the physical disk? Did it work on real hardware before? Try remembering what you changed in the meantime (or if you have a backup from before try getting a "diff")
Invisible Tape

Re:reboot when jumping to kernel

Post by Invisible Tape »

I'm pretty sure the a20 is enabled, i am checking it but i might be doing it wrong.

Code: Select all

ENABLEA20:

   cli
   
.3:   in al, 0x64         ; check if input port is open
       and al, 1   
       jnz .3             
       mov al, 0xD1   
       out 0x64, al   
.4:   in al, 0x64         ; check if input port is open    
       and al, 1   
       jnz .4     
       mov al, 0xDF
       out 0x60, al   
.5:   in al, 0x64         ; check if input port is open     
       and al, 1   
       jnz .5
        
CHECKA20:

        mov al, 0xD0
        out 0x64, al
.6:    in al, 0x64        ; wait for the data to get in
        test al, 1
        jz .6
        in al, 0x60
        test al, 2
        mov si, A20ERRO
        jz ERROR

   sti 
and as for loading the kernel, it worked before and all i've done to it is added that last bit to load my last sector. My kernel is 8.87 kB large:

Code: Select all

mov dl, [BOOTDRV]
   int 0x13          ; reset disk drive
   jc LOADKERNEL
   
   mov ax, 0xFFFF
   mov es, ax
   mov bx, 0x10        ; loaded to 0xFFFF:0x10 (0x100000)     
   mov ah, 0x02 
   mov al, 0x11      ; num of sectors to read (2 = 1kb)
   mov ch, 0x00        
   mov cl, 0x02        ; start at second sector as the first is the bootloader. One thing i wonder is does this start at 0 or 1?     
   mov dh, 0x00
   int 0x13
   mov si, LOADER1
   jc ERROR
   
   mov ax, 0xFFFF
   mov es, ax
   mov bx, 0x2210      ; loaded to 0xFFFF:0x2210 (0x102200) 
        mov ah, 0x02
        mov al, 0x01      ; num of sectors to read (2 = 1kb)
        mov ch, 0x00
        mov cl, 0x01 
        mov dh, 0x01
        int 0x13   
        mov si, LOADER2
   jc ERROR
   
   mov dx, 0x3F2
   mov al, 0xC
   out dx, al          ; stop the disk motor
And it did work on real hardware before. The only thing i've messed with, other than the loading part, is the a20 stuff, and only for checking that it is on.

ps: sorry for the screwy indentation
AR

Re:reboot when jumping to kernel

Post by AR »

The only thing that looks unusual here is getting the BIOS to read directly to 1MB, with A20 off it should work theoretically.

The code I use to enable A20 looks similar to yours but you do it differently, you can try this code and see if it helps:

Code: Select all

cli

   mov CX, 5   ;Retry 5 times

   .A20Method1:      

   .Wait1:   ;Wait for the controller to be ready for a command
   xor AX, AX
   in AL, 64h
   bt AX, 1   ;Test for bit 1
   jc .Wait1

   mov AL, 0D0h   ;Send the command D0h: read output port.
   out 64h, AL

   .WaitData1:   ;Wait for data to become avaliable
   xor AX, AX
   in AL, 64h
   bt AX, 0
   jnc .WaitData1

   xor AX, AX   ;Read the current status from port 60h
   in AL, 60h

   push AX      ;Save the current value of AX

   .Wait2:   ;Wait for the controller to be ready for a command
   in AL, 64h
   bt AX, 1
   jc .Wait2

   mov AL, 0D1h      ;Tell the controller we want to write the status byte
   out 64h, AL   

   .Wait3:      ;Wait for the controller to be ready for the data
   xor AX, AX
   in AL, 64h
   bt AX, 1
   jc .Wait3

   pop AX   ;Reaccquire AX from the stack
   or AL, 00000010b ;Turn on the A20 enable bit by writing the ON value to port 60h
   out 60h, AL

   ;Make Sure the status was set correctly, otherwise we have to try again

   .Wait4:   ;Wait for the controller to be ready for a command
   xor AX, AX
   in AL, 64h
   bt AX, 1
   jc .Wait4

   mov AL, 0D0h   ;Send the command D0h: read output port.
   out 64h, AL   

   .WaitData2:   ;Wait for the controller to be ready for reading again
   xor AX, AX
   in AL, 64h
   bt AX, 0
   jnc .WaitData2

   xor AX, AX   ;Read the current port status from port 60h
   in AL, 60h   
   bt AX, 1   ;Is A20 enabled?
   jc .worked

   loop .A20Method1
   
   mov SI, A20Failed
   call PrintString
   hlt
   
   .worked:
   sti
This code is from http://www.osdever.net/tutorials/a20.php?the_id=4 when I used it I altered the comments though (I must have been bored or something), the original is more informative.

I'm out of ideas if this doesn't work
Invisible Tape

Re:reboot when jumping to kernel

Post by Invisible Tape »

That didn't work. Still the same reboot at the same instruction. I have no clue, any ideas before i trash my code?
Post Reply