Identity mapping first meg of memory

Programming, for all ages and all languages.
Post Reply
tedavids
Posts: 11
Joined: Sun Apr 26, 2026 6:59 am

Identity mapping first meg of memory

Post by tedavids »

I am trying to identity map 0x0-0xFFFF.

I am extending the higher half tutorial found here: https://wiki.osdev.org/Multiboot_1_High ... Bare_Bones

I have added a page table (page_table_000) which debug seems to show looks ok:
(gdb) x/256xw &page_table_000
0xc010f000: 0x00000003 0x00001003 0x00002003 0x00003003
0xc010f010: 0x00004003 0x00005003 0x00006003 0x00007003
0xc010f020: 0x00008003 0x00009003 0x0000a003 0x0000b003
0xc010f030: 0x0000c003 0x0000d003 0x0000e003 0x0000f003
0xc010f040: 0x00010003 0x00011003 0x00012003 0x00013003
0xc010f050: 0x00014003 0x00015003 0x00016003 0x00017003
0xc010f060: 0x00018003 0x00019003 0x0001a003 0x0001b003
0xc010f070: 0x0001c003 0x0001d003 0x0001e003 0x0001f003
0xc010f080: 0x00020003 0x00021003 0x00022003 0x00023003
...
The identity mapping looks ok to me.

Once I no longer need the identity mapping to get to my kernel (I'm using the 0xC... addresses) and the tutorial wants to remove the first meg identity mapping. I try to replace the first meg with my mapping:
_start2:
# At this point, paging is fully set up and enabled.

# Unmap the identity mapping as it is now unnecessary.
# replace with the identity mapping for the first meg
movl $(page_table_000 + 0x003), page_directory + 0

# Reload crc3 to force a TLB flush so the changes to take effect.
movl %cr3, %ecx
movl %ecx, %cr3
The addresses look good to me:
(gdb) p/x &page_table_000
$12 = 0xc010f000
(gdb) p/x (long)page_directory
$13 = 0xc010f003
so I think when I get past the movl %ecx, %cr3 above I should now be able to view an address in the 1st meg.
But when I try I get:
(gdb) p/x *0x9500
❌️ Cannot access memory at address 0x9500
I'm hoping I'm doing something obviously wrong. If not, how would you proceed in debugging this?

TD
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: Identity mapping first meg of memory

Post by Octocontrabass »

tedavids wrote: Mon Jun 01, 2026 12:57 pm

Code: Select all

	movl $(page_table_000 + 0x003), page_directory + 0
Does the symbol "page_table_000" refer to a physical address or a virtual address? Which kind of address goes in the paging structures?
tedavids
Posts: 11
Joined: Sun Apr 26, 2026 6:59 am

Re: Identity mapping first meg of memory

Post by tedavids »

It is a virtual address, and is addressable as gdb can dump the memory using it.

My understanding is that the 'physical' (linear?) address goes in the paging structure. Since it is the first page directory entry, it should be 0x0-0xBFFFFF virtual addresses, it is identity mapped. I think

Paging is set up and working.

This is how things are set up in output.txt (my link file):
.bss 0xc010e000 0x3000 object/boot.o
0xc010e000 page_directory
0xc010f000 page_table_000
0xc0110000 page_table_C00
I'm not at all sure how to debug this. There must be something I don't understand. But for the life of me, I don't know what it is.

TD

ps: The full code is here: https://github.com/tedavids/DragonOS
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: Identity mapping first meg of memory

Post by Octocontrabass »

tedavids wrote: Mon Jun 01, 2026 6:14 pmIt is a virtual address,

My understanding is that the 'physical' (linear?) address goes in the paging structure.
Right. You're putting a virtual address in the page directory instead of a physical address, so it's not going to work.
tedavids
Posts: 11
Joined: Sun Apr 26, 2026 6:59 am

Re: Identity mapping first meg of memory

Post by tedavids »

I guess I'm being thick. I want to map 0x0-0xFFFF as virtual = real. The reason is I want to get to the multiboot info data structure which is at 0x9500.

For example if I want page 0x0, to map to actual address 0x0. Shouldn't the page table entry 0 be 0x00000003?, and page 0x1 page table entry 1 should have 0x00001003?

and then place the page table at the first directory with the present and RW flags set?

so to look at address 0x9500 page table entry 149 should have 0x00095003.

How should I set up the 3 examples above? Maybe that will make things clearer for me.

And thank you for your help, I know you don't have to.

TD
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: Identity mapping first meg of memory

Post by Octocontrabass »

tedavids wrote: Mon Jun 01, 2026 7:53 pmFor example if I want page 0x0, to map to actual address 0x0. Shouldn't the page table entry 0 be 0x00000003?, and page 0x1 page table entry 1 should have 0x00001003?
Yes.
tedavids wrote: Mon Jun 01, 2026 7:53 pmand then place the page table at the first directory with the present and RW flags set?
Yes, but you need to place the physical address of the page table in the page directory entry. Right now your code places the virtual address of the page table in the page directory entry.
tedavids
Posts: 11
Joined: Sun Apr 26, 2026 6:59 am

Re: Identity mapping first meg of memory

Post by tedavids »

OK,

So when I look at output.txt (my linker file)
.bss 0xc010e000 0x3000 object/boot.o
0xc010e000 page_directory #physical address 0x103000
0xc010f000 page_table_000 #physical address 0x10f000
0xc0110000 page_table_C00 #physical address 0x110000
I know page_table_000 while its virtual address is 0xc010f000, I know it resides in memory at 0x010f000, so I put the 0x010f00 in my page directory. And lo and behold, it now works.

I never would have figured that out on my own. I went back to the things I've been reading and noticed that one does says physical, most just say address.

I'm going to suggest an edit, that the word 'physical' be bolded. Maybe it will help someone else.

Thanks again! Hopefully I won't have to ask anything else for a while.

TD
Post Reply