1

So I have ran into a problem which I've been stuck on now for what seems like eternity, about 3 days without sleep trying to solve the issue on my own now, and it's kinda depressing to me as I feel as if it should honestly be a relatively simple task to load a simple table and perform a far jump into 32-bit mode and boom! Have it working with the snap of my figures. The problem is causing my computer to reboot every time I load the GDT and perform a far jump however, as I have seen with numerous other posts and people dealing with the same issue. I am loading from my bootloader using 'INT 0x13, AX = 0x20A' with 'ES:BX = 0x1000:0'. Right before the 'CLI LGDT [GDT_END]' instruction, if I perform a 'JMP $' instruction, it will successfully print the string about having made it to the kernel. However, the second I load the GDT, whether loading via an %include or pasting the include's contents directly within the kernel itself, the error persists in an endless reboot.

Any suggestions in what I may be doing wrong would surely be lovely! Days spent and I can't seem to find and answer in resolving my issue anywhere, despite tons of posts seeming to resemble the same issue. Here is the kernel code I have typed out over and over again probably several thousands of times already... I tried making it look as legible as I possibly can, and tried all solutions I could find that seemed to help others. This seems to be my last resort.. If the bootloader is needed I can post it as well, however, like I said, it does in fact make it to the kernel loaded in at segment: 0x1000 offset: 0. Which I usually never use ORG, and honestly have no idea what is actually does or is doing, nor can I find clear explanations on it either, but with or without it, either way, it doesn't work. Assembled with NASM in windows cmd line using 'nasm -okernel.bin kernel.asm'.

    BITS 16
    ORG 0x10000
    JMP FLOW_KERNEL_START
    NOP

;----------------------------
;  GLOBAL DESCRIPTOR TABLE
;----------------------------
GDT_START:
    dq 0

GDT_CODE_SEGMENT:
    dw 0xFFFF
    dw 0
    db 0
    db 10011010b
    db 11001111b
    db 0

GDT_DATA_SEGMENT:
    dw 0xFFFF
    dw 0
    db 0
    db 10010010b
    db 11001111b
    db 0

GDT_END:
    dw GDT_END - GDT_START - 1
    dd GDT_START

;----------------------------
;       INCLUDES
;----------------------------
;%INCLUDE 'BIO_Land\gdt.asm'
;----------------------------

FLOW_KERNEL_START:
            ; SET SEGMENTS AND BOOT DEVICE VARIABLES
    XOR AX, AX
    CLI
    MOV SS, AX
    MOV SP, 0x9000
    STI

    MOV AX, 0x1000
    MOV DS, AX
    MOV ES, AX
    MOV FS, AX
    MOV GS, AX
    MOV byte [VAR_BOOTDEV], DL
    CALL FUNC_GOOD
    MOV AX, 0
    INT 0x16

            ; LOAD GDT TABLE AND MASK 32-BIT PROTECTED MODE FLAG
    CLI
    LGDT [GDT_END]
    MOV EAX, 0x10
    MOV DS, EAX
    MOV ES, EAX
    MOV FS, EAX
    MOV GS, EAX
    MOV SS, EAX
    MOV EAX, CR0
    OR EAX, 1
    MOV CR0, EAX
    JMP dword 0x8:FLOW_PROTECTED_MODE
    NOP

BITS 32
FLOW_PROTECTED_MODE:
    STI
    MOV byte [0xB8000], 'O'
    MOV byte [0xB8001], 0x0F
    MOV byte [0xB8002], 'O'
    MOV byte [0xB8003], 0x0F
    MOV byte [0xB8004], 'O'
    MOV byte [0xB8005], 0x0F
    MOV byte [0xB8006], 'O'
    MOV byte [0xB8007], 0x0F
    MOV byte [0xB8008], 'O'
    MOV byte [0xB8009], 0x0F
    JMP $

;----------------------------
;       FUNCTIONS
;----------------------------
FUNC_GOOD:
    MOV SI, VAR_STRING
    CALL FUNC_PRINT
    RET

FUNC_PRINT:
    MOV AH, 0x0E
    FUNC_PRINT_LOOP:
        LODSB
        CMP AL, 0
        JE FUNC_PRINT_DONE
        INT 0x10
        JMP FUNC_PRINT_LOOP
    FUNC_PRINT_DONE:
        RET
;----------------------------
;       VARIABLES
;----------------------------
VAR_BOOTDEV db 0

;----------------------------
;       STRINGS
;----------------------------
VAR_STRING db 'Hello world! You made it to the kernel!', 0

EDIT: I have changed the the JMP $ to an INT 0x16 to make things more simple. It boots to it just fine as mentioned before but on keypress is a reboot. I have changed the ORG to 0x1000 as well as 0x10000. I'm unsure on how I would load at address 0x7C00 without attaching it to being inside the bootloader itself, but that being said I have also tried putting a buffer label at the end of the bootloader and loading the kernel at it, assuming the address after the bootloader being 0x7E00 and using it as the ORG. I have also tried omitting the ORG entirely (as it is already being set via the DS is it not?) and then changing the 0x8:FLOW_PROTECTED_MODE to 0x8:FLOW_PROTECTED_MODE+0x10000. I have also tried using JMP 0x8:$$+$ among numerous other things. BOSHC is saying exactly what I was expecting to find that the JMPF 0x8:0x00001065 cannot be resolved. I am assuming that the kernel IS in fact loaded somewhere within memory as it does say Hello world!, but I just cannot for the life of me figure out how to find the location correctly or what the problem is.

GodDamn
  • 161
  • 1
  • 8
  • 2
    Run your code under an emulator like BOCHS that will show you the reason for a triple-fault reset, and has a built-in debugger that understands segmentation / GDT. – Peter Cordes Jun 06 '20 at 13:27
  • 2
    `Org 0x10000` in 16-bit code won't do what you think it will. NASM will wrap that to 0x0000 for 16-bit addresses. In combo with all segment registers being set to 0x1000 the code will appear to be running at 0x1000:0x0000. If you are going to load a GDT and jump to prot mode I highly recommend using `org 0x7c00` and load the segment registers with 0x0000. This will fix other problem-GDT (and IDT) addresses are not segment:offset but linear. By setting `org 0x7c00` and using a segment of 0x0000 will give you addresses that also happen to match linear addreses and they don't need to be adjusted. – Michael Petch Jun 06 '20 at 13:31
  • I created a 1.44MB image file. My bootloader has a fat12 filesystem reading sector 35 for the kernel file and loading it. I created an img file consisting of all 0s and copied through a hex editor my usb drive to the file location and booted into bochs however it aswell is repeating a message 'Booting from floppy' ? Edit: I believe I gotta mess with bocsh settings. Thanks for the advice though. I'll mess with it and hope I can figure it out. – GodDamn Jun 06 '20 at 14:28
  • 1
    At first I thought it was a bootloader so I said 0x7c00. You could load your kernel starting at 0x0000:0x7e00 right after the bootloader (and have the stack below the bootloader at 0x0000:0x7c00. Or you could place your kernel at 0x0000:0x1000. All of these example use a segment of 0x0000 so you don't have to fudge around by altering the GDT address or the FAR JMP. – Michael Petch Jun 07 '20 at 17:20

0 Answers0