Page 1 of 1

Stange system panic upon writing to cr0

Posted: Mon Nov 28, 2022 9:16 am
by jaihsonk
Hey everyone!
I'm having a strange bug occur when writing to the cr0 register. On QEMU, everything is fine. But when I boot on KVM or a real machine, it panics. here's a snippet

Code: Select all

.load_protected:
    cli
    lgdt[gdt_descriptor]
    mov eax, cr0
    or eax, 0x1
    mov cr0, eax
    jmp CODE_SEG:load32
the full source code is here: https://serpaeos.sourceforge.io (src/boot/boot.asm)
Maybe I'm totally blind to some dumb mistake, but I can't seem to figure this one out! Sorry if this turns out to be a dumb question lol

Thanks in advance,

Jason

Re: Stange system panic upon writing to cr0

Posted: Mon Nov 28, 2022 10:23 am
by nullplan
Well, there is nothing wrong with the snippet. Therefore, the problem is elsewhere. And the only other moving parts here are the GDTR you are loading and the contents of the GDT, so what are those?

Re: Stange system panic upon writing to cr0

Posted: Mon Nov 28, 2022 11:25 am
by Octocontrabass
jaihsonk wrote:On QEMU, everything is fine. But when I boot on KVM or a real machine, it panics.
QEMU's TCG doesn't enforce segment limits. You switched to protected mode, but you're still using the data segments from real mode, and real mode data segments have a limit of 0xFFFF bytes. The exception occurs when you try to access data above 0xFFFF.

Re: Stange system panic upon writing to cr0

Posted: Mon Nov 28, 2022 12:36 pm
by jaihsonk
@nullplan, the problem is not with loading the GDT. I placed a

Code: Select all

jmp $
after each instruction to see where the problem is, and the problem is definitely at the

Code: Select all

mov cr0, eax 
instruction.
That would mean that the addressing fault would not have an opportunity to arise, as @Octocontrabass suggests, because the system would panic before it had a chance to

Code: Select all

jmp CODE_SEG:load32
.
Is there something wrong with that reasoning?

@nullplan, you can find the entire gdt at https://sourceforge.net/projects/serpaeos/

Re: Stange system panic upon writing to cr0

Posted: Mon Nov 28, 2022 12:55 pm
by Octocontrabass
jaihsonk wrote:I placed a

Code: Select all

jmp $
after each instruction to see where the problem is, and the problem is definitely at the

Code: Select all

mov cr0, eax 
instruction.
The instruction immediately following the MOV to CR0 that enables protected mode must be a far JMP or far CALL. Your "jmp $" is not a far JMP, so the result is undefined behavior.

Re: Stange system panic upon writing to cr0

Posted: Mon Nov 28, 2022 1:50 pm
by jaihsonk
OK I get the point. How can I get 32 bit addressing space then? Should I enable a20 in bootloader instead of kernel loader? If you know of any good articles that'd be appreciated thanks

Re: Stange system panic upon writing to cr0

Posted: Mon Nov 28, 2022 2:37 pm
by Octocontrabass
jaihsonk wrote:How can I get 32 bit addressing space then?
You can get 32-bit addressing by fixing your code. Right now your code skips some required initialization steps.

Or, depending on what you're doing with 32-bit addressing, you might instead prefer to use the BIOS INT 0x15 AH=0x87 or unreal mode. Those methods have the added benefit that you can continue to use other BIOS functions, such as INT 0x13 to read the disk; you can't use the BIOS once you've switched to protected mode.
jaihsonk wrote:Should I enable a20 in bootloader instead of kernel loader?
You should enable A20 before directly accessing any address above 1MB. (You shouldn't enable A20 before using INT 0x15 AH=0x87.)
jaihsonk wrote:If you know of any good articles that'd be appreciated thanks
This article has a brief overview of the steps required to switch to protected mode. (Personally, I don't think it's necessary to disable NMI - if one arrives while you're switching modes, it means there's a hardware problem.)

Or, if you're interested in unreal mode, you can read more about it here. Keep in mind the BIOS can exit unreal mode at any time without warning; you'll have to install a #GP handler that enters unreal mode if you want it to be reliable.

Or, if you're interested in INT 0x15 AH=0x87, you can read more about it here. This function handles A20 automatically, and on some PCs it will disable A20 before returning, so you shouldn't call this function after you enable A20.

Re: Stange system panic upon writing to cr0

Posted: Tue Nov 29, 2022 1:47 pm
by jaihsonk
OK so I've updated my boot loader and it still happens. I'm booting into protected mode, not unreal btw.
interrupts disabled, a20 enabled, and gdt loaded before jumping to load32.
Interestingly, the problem is lo longer in the real mode part, but in my ata driver. when loading data to 0x100000, it panics. Here is a snippet:

Code: Select all

.copy:
    xor ax, ax
    in ax, dx
    mov word[edi], ax ;this is where the panic happens (edi is set to 0x100000 and counting)
    dec ecx
    add edi, 2
    cmp ecx, 0
    ja .copy
I don't see why addressing memory above 1MB should give a problem since I've done everything required (cli, a20, and gdt)
This is really frustrating me lol #-o

Re: Stange system panic upon writing to cr0

Posted: Tue Nov 29, 2022 1:55 pm
by Octocontrabass
It's impossible to say what's wrong without seeing more of your code.

Re: Stange system panic upon writing to cr0

Posted: Tue Nov 29, 2022 1:59 pm
by jaihsonk

Re: Stange system panic upon writing to cr0

Posted: Tue Nov 29, 2022 2:01 pm
by Octocontrabass
I can't find the current version of your code anywhere on that page.

Re: Stange system panic upon writing to cr0

Posted: Tue Nov 29, 2022 2:25 pm
by jaihsonk
kk sory now it works

Re: Stange system panic upon writing to cr0

Posted: Tue Nov 29, 2022 2:42 pm
by Octocontrabass
You need to load your data segment selector into all of the data segment registers you're using.

Re: Stange system panic upon writing to cr0

Posted: Tue Nov 29, 2022 5:20 pm
by jaihsonk
Ah! Thanks so much! I knew it would be some dumb problem :roll:
Thanks for your help!