Can't jump or call kernel loaded at 0x8000

后端 未结 1 961
予麋鹿
予麋鹿 2021-01-13 08:32

I am trying to develop an operating system. The design is this: I have a bootloader loaded at 0x7c00 which loads the second stage and jumps to it at 0x7e00. The second stage

相关标签:
1条回答
  • 2021-01-13 09:10

    Problem Reading Stage 3

    In the second stage you load the third stage doing this:

       Read:
             mov ah , 02h      ; Setup AH
             mov al , 01h      ; Setup AL
             mov ch , 00h
             mov cl , 03h
             mov dh , 00h
             mov dl , [0x500]
             mov ax , 0x800    ; Destroy contents of AX 
             mov es , ax       ; Setup ES=0x800
             xor bx , bx
             int 13h
    

    I have marked the lines with the problems. You effectively set up AX to get ready for the read and then overwrite the values with 0x800 to set up ES. Move setting up ES before you setup AH and AL. Modify the code to look like:

       Read:
             mov ax , 0x800 
             mov es , ax       ; Setup ES=0x800
             mov ah , 02h      ; Setup AH
             mov al , 01h      ; Setup AL
             mov ch , 00h
             mov cl , 03h
             mov dh , 00h
             mov dl , [0x500]
             xor bx , bx
             int 13h
    

    This likely prevents your second stage from loading the 3rd stage properly.


    Other Issues

    At the end of the bootloader you have:

        db 0xAA
        db 0x55
    

    This is backwards and should be:

        db 0x55
        db 0xAA
    

    You could have written it as:

        dw 0xAA55
    

    The issue appears to be that you didn't take little endianness into account when defining these bytes.


    You properly jump over the BIOS Parameter Block in the bootloader, but the BPB needs to start at the 4th byte in the boot sector. You can force a 2-byte JMP using the short modifier. You can then place a nop after the jump so that the BPB starts at the 4th byte.

    Change:

      jmp Reset
      bpbOEM DB "SKULLOS " 
    

    To:

      jmp short Reset
      nop         ; 1 byte padding as BPB needs to start at 4th byte (short jmp takes 2 bytes)
      bpbOEM DB "SKULLOS " 
    

    mov sp , 0xFFFF should probably be mov sp, 0x0000. This is just a minor nitpick. Having the stack on a WORD boundary (even addresses) performs better on 8086 processors. Since you are not in real mode very long it doesn't much matter at all. Usually you'd use mov sp, 0x0000 in your case because the first WORD pushed will be at 0x9000:0xfffe since 2 is subtracted from SP first and then the WORD pushed onto the stack. Effectively with SP=0x0000 the stack will start by wrapping to the top of the 64k segment.


    You don't need to JMP from label to label if the label is right after the JMP. Instructions like:

        jmp Set 
    Set: 
    

    does nothing but waste space and take CPU cycles. I noticed you did that in quite a few places. This isn't part of your problem, just an observation. The FAR JUMP jmp (code-gdt_start):transfer_control followed by the label is fine since that is used to to set the CS descriptor properly (for protected mode)


    When doing disk access with int 13h you should be using the boot drive number passed by the BIOS to your bootloader as the value for DL. Your first and second stages have code like:

    mov dl , 00h
    

    This always assumes you are reading from the first floppy (A:). If you want to use your code on a boot drive other than Floppy A: you'll want to remove this

    0 讨论(0)
提交回复
热议问题