Reading high memory causes page fault in UEFI Bootloader

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
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

I try to read memory mapped above 0xffff800000000000 but it gives a page fault at CR2=00000000fee00020. even if I map that address (which looks like the LAPIC) it gives a page fault at 0xffff800000000000.
- I have one of the latest qemu version 7.2.0 which supports 5 level paging, is it related to the problem ?
- I map the kernel with 2 MB Pages and Global Paging
- Here is the "info mem" dump in QEMU:

Code: Select all

0000000000000000-00000000000a0000 00000000000a0000 -rw
0000000000100000-0000000080000000 000000007ff00000 -rw
00000000b0000000-00000000c0000000 0000000010000000 -rw
00000000ffc00000-0000000180000000 0000000080400000 -rw
ffff800000000000-ffff800000200000 0000000000200000  - rw
- Here is the "info registers" dump :

Code: Select all

CPU#0
RAX=0000000000000000 RBX=000000007f17d4e8 RCX=000000007f170548 RDX=0000000000000002
RSI=0000000000000032 RDI=000000007f170548 RBP=00000000000004d0 RSP=000000007fe9ca70
R8 =0000000000000000 R9 =0000000000000000 R10=000000000000000a R11=ffff800000001000
R12=000000007fe9cbb8 R13=000000000000000e R14=000000007f5a8018 R15=000000007e362000
RIP=000000007f166148 RFL=00000046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     000000007f9de000 00000047
IDT=     000000007f593018 00000fff
CR0=80010033 CR2=00000000fee00020 CR3=0000000000001000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000d00
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
XMM08=0000000000000000 0000000000000000 XMM09=0000000000000000 0000000000000000
XMM10=0000000000000000 0000000000000000 XMM11=0000000000000000 0000000000000000
XMM12=0000000000000000 0000000000000000 XMM13=0000000000000000 0000000000000000
XMM14=0000000000000000 0000000000000000 XMM15=0000000000000000 0000000000000000
Here is the testing instruction :

Code: Select all

QemuWriteSerialMessage(ToStringUint64(*(UINT64*)(0xffff800000000000)));
Operating System Link : https://github.com/NXTdevosc1/New-Operating-System
src/boot/efi/amd64/
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Reading high memory causes page fault in UEFI Bootloader

Post by Octocontrabass »

devc1 wrote:- Here is the "info mem" dump in QEMU:
Also check "info tlb".
devc1 wrote:- Here is the "info registers" dump :
You'll get more useful information using "-d int" to see the CPU state during the first exception, and it'll include the page fault error code.
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

These are the last tlb entries, something looks weird maybe ?

Code: Select all

000000017ffff000: 000000017ffff000 --------W
ffff800000000000: 0000800000000000 --P-----W
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Reading high memory causes page fault in UEFI Bootloader

Post by Octocontrabass »

Yeah, the physical address is 0x800000000000, that looks very weird. What is the physical address supposed to be?
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

Oh I found it, I mapped the kernel to Physical address 0xffff80000000000 by error :

Code: Select all

BlMapToSystemSpace(NosInitData.NosKernelImageBase, Convert2MBPages(NosInitData.NosKernelImageSize));
NosInitData.NosKernelImageBase contains the virtual address of the kernel not the physical one, I changed it to NosInitData.NosKernelPhysicalBase.

https://github.com/NXTdevosc1/New-Opera ... /map.c#L55

I will do some changes and see if it works.
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

It still didn't fix the problem but when I did the "info tlb" thing I came into a conclusion :
- The serial file says

Code: Select all

NOS_IMAGE:
FFFF800000000000
7E362000 // Physical Kernel Address
10000
1
But info tlb says :

Code: Select all

ffff800000000000: 000000007e200000 --P-----W
- First the physical address should be also 2MB aligned since I'm using large pages
- And in the Page->PhysicalAddress I should right shift by 21 instead of 12.
I will try to fix this.

And tell me if there is anything wrong with my conclusion.

I want to use Large pages for System Space memory to increase the performance.
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Reading high memory causes page fault in UEFI Bootloader

Post by Octocontrabass »

devc1 wrote:- First the physical address should be also 2MB aligned since I'm using large pages
Yes.
devc1 wrote:- And in the Page->PhysicalAddress I should right shift by 21 instead of 12.
That depends on how you access your page tables. The address bits are always at the same location, there are just more of them for smaller pages. If you access them as uint64_t, there is no shifting at all. If you use structs, you need a different struct for each type of entry.
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

"info tlb" shows weird physical addresses using large pages like 0x200000 where the actual one is 0x7E00000, can you look into the repository and tell me if there is anything wrong with my mapping : https://github.com/NXTdevosc1/New-Opera ... md64/map.c

BlMapMemory()

serial.txt in the root directory has all the info.
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Reading high memory causes page fault in UEFI Bootloader

Post by Octocontrabass »

You're shifting by too many bits somewhere. The upper address bits are always at the same location in page table entries. Bigger pages just have fewer address bits.
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

So I don't need to shift the physical address but it just needs to be 2mb aligned.
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

Well it still gives page fault at 0000000fee00020, right after the call to NosEntryPoint()
But the TLB seems to show the correct value of the physical address.

I think that there is a problem in the loader.
Also I'm changing the page table without changing the IDT or the GDT.
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Reading high memory causes page fault in UEFI Bootloader

Post by Octocontrabass »

devc1 wrote:Also I'm changing the page table without changing the IDT or the GDT.
As long as you don't do anything that might cause an exception, you don't need an IDT or GDT at all.

What does QEMU's "-d int" log say about it?
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

Bruh in UEFI Mode, running QEMU with -d int takes forever.
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Reading high memory causes page fault in UEFI Bootloader

Post by Octocontrabass »

Having that kind of debugging information is worth the wait.

You can try adding "-D debuglog.txt" to direct the output to a file, it might speed things up.
devc1
Member
Member
Posts: 439
Joined: Fri Feb 11, 2022 4:55 am
Location: behind the keyboard

Re: Reading high memory causes page fault in UEFI Bootloader

Post by devc1 »

Now there is no page fault, but calling the entry point causes the page fault. I read some bytes from the entry point to the serial.txt file and it showed that there is nothing there. So I think now I have a loader problem.

I found out (from my previous OS) that instead of Sections = Header + sizeofOptionalHeader I had to do &Header->OptionalHeader + sizeofOptionalHeader.

Now it works the entry function sets RAX to RAX=00000000cafebabe

Anyway thank you so much for help.
Post Reply