I'm trying to understand how memory is laid out in the kernel.
Specifically, I have a tool that will let me view physical memory on
a host and I'm using that to try to view data structures in the
kernel, so I'm starting with a virtual address and translating it to
a physical address. As I currently understand it, there's three
major regions of linux kernel memory for a typical x86 machine:
#1 -- 0xc0000000 - high_memory (linearly mapped to physical memory)
#2 -- high_memory - 0xfe000000 (paged)
#3 -- 0xfe000000 - 0xffffffff (other random mappings)
I can successfully view memory in region #1. So right now I'm
interested in memory region #2. My understanding is that the
starting place for the kernel page table mapping is the master kernel
page global directory (aka swapper_pg_dir). Given that starting
point, here's where I'm at right now...
The first entry below is the 769th entry in the kernel master page
global
directory, or put another way, it is equal to swapper_pg_dir[768]. This
is the first entry for kernel memory (the first 768 entries map linear
addresses lower than 0xc0000000).
00000c00| 67 d0 a6 17 67 c0 a6 17 67 b0 a6 17 67 70 5a 3a
g...g...g...gpZ:
00000c10| 67 50 9b 3b 67 70 11 1b 67 f0 f9 39 67 00 07 1c
gP.;gp..g..9g...
00000c20| 67 80 28 3f 67 40 91 3b 67 70 f8 2a 67 20 49 3b g.(?
g@.;gp.*g I;
00000c30| 67 e0 0a 02 67 90 3e 12 67 e0 3e 12 67 60 dc 07
g...g.>.g.>.g`..
00000c40| 67 90 3d 12 67 d0 3a 1b 67 10 64 07 67 b0 e4 0d
g.=.g.:.g.d.g...
00000c50| 67 50 ac 02 67 00 fe 06 67 60 87 35 67 20 fb 0b
gP..g...g`.5g ..
00000c60| 67 90 35 0f 67 d0 18 0d 67 c0 e9 2a 67 f0 3b 12 g.
5.g...g..*g.;.
00000c70| 67 d0 20 12 67 b0 cc 10 67 d0 35 10 67 c0 39 10
g. .g...g.5.g.9.
00000c80| 67 80 95 10 67 c0 db 10 67 30 e2 10 67 e0 65 11
g...g...g0..g.e.
00000c90| 67 b0 74 11 67 a0 83 11 67 00 90 11 67 b0 e1 11
g.t.g...g...g...
00000ca0| 67 b0 7d 12 67 e0 a4 12 67 10 b0 12 67 30 51 13
g.}.g...g...g0Q.
00000cb0| 67 30 d4 13 67 00 22 14 67 20 36 14 67 f0 35 14
g0..g.".g 6.g.5.
00000cc0| 67 f0 37 14 67 60 4d 14 67 40 fa 14 67 f0 0d 15 g.
7.g`M.g@..g...
00000cd0| 67 60 11 15 67 f0 15 15 67 70 17 15 67 90 72 15
g`..g...gp..g.r.
00000ce0| 67 70 76 15 67 40 7e 15 67 00 7f 15 67 b0 87 15
gpv.g@~.g...g...
00000cf0| 67 a0 8a 15 67 40 d3 15 67 90 d6 15 67 40 44 16
g...g@..g...g@D.
00000d00| 67 80 59 16 67 20 09 17 00 00 00 00 00 00 00 00
g.Y.g ..........
00000d10| 67 f0 91 11 00 00 00 00 00 00 00 00 00 00 00 00
g...............
Note: This system has 256 MB ram; PAE is disabled; and is running
2.6.12.
The bottom 12 bits of each entry are flags as follows:
#define _PAGE_PRESENT 0x001
#define _PAGE_RW 0x002
#define _PAGE_USER 0x004
#define _PAGE_PWT 0x008
#define _PAGE_PCD 0x010
#define _PAGE_ACCESSED 0x020
#define _PAGE_DIRTY 0x040
#define _PAGE_PSE 0x080 /* 4 MB (or 2MB) page, Pentium+, if
present.. */
#define _PAGE_GLOBAL 0x100 /* Global TLB entry PPro+ */
#define _PAGE_UNUSED1 0x200 /* available for programmer */
#define _PAGE_UNUSED2 0x400
#define _PAGE_UNUSED3 0x800
The rest *should* be the physical address, but that doesn't really
seem to make sense to me. For example, look at the last entry in the
table:
0x1191f067
Flags Set:
-- _PAGE_PRESENT
-- _PAGE_RW
-- _PAGE_USER
-- _PAGE_ACCESSED
-- _PAGE_DIRTY
Looking at this without the flags:
0x1191f067 & 0xfffff000 = 0x1191f000
Coverting this to a virtual address:
0x1191f000 + 0xc0000000 = 0xd191f000
But this value is above the high_memory line for this computer:
high_memory = 0xd0800000
So why does an entry in the kernel master global directory point to
an address that is not linearly mapped (i.e., not between 0xc0000000
and high_memory)? From this, it looks like I'd have to go back into
the page tables to resolve that memory address, but it seems wrong
that I'd have to use page tables to complete a page table lookup.
Right now, that's the point that I'm stuck on.
So my real question is, where has my reasoning gone astray? Am I
interpreting the memory values wrong or is my understanding of the
memory regions wrong or ???
Thanks,
bryan
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/