* Petersson, Mats <Mats.Petersson@xxxxxxx> [2006-09-01 11:52]:
>
>
> > -----Original Message-----
> > From: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
> > [mailto:xen-devel-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of
> > PUCCETTI Armand
> > Sent: 01 September 2006 17:11
> > To: xen-devel@xxxxxxxxxxxxxxxxxxx
> > Subject: [Xen-devel] idle_pg_tables??
> >
> > In the paging mechanism of XEN what is the role of the variable
> > 'idle_pg_table*' variables ??
> >
> > For a 4-levels paging system these variables are defined in
> > x86_64.S and
> > partially initialised.
> > Here is the code, copied from x86_64.S:
> >
> > __________________________________________________
> > ...
> >
> > /* Initial PML4 -- level-4 page table. */
> > .org 0x2000
> > ENTRY(idle_pg_table)
> > ENTRY(idle_pg_table_4)
> > .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0]
> > .fill 261,8,0
> > .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262]
> >
> > /* Initial PDP -- level-3 page table. */
> > .org 0x3000
> > ENTRY(idle_pg_table_l3)
> > .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
> >
> > /* Initial PDE -- level-2 page table. Maps first 64MB
> > physical memory. */
> > .org 0x4000
> > ENTRY(idle_pg_table_l2)
> > .macro identmap from=0, count=32
> > .if \count-1
> > identmap "(\from+0)","(\count/2)"
> > identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
> > .else
> > .quad 0x00000000000001e3 + \from
> > .endif
> > .endm
> > identmap
> >
> > .org 0x4000 + PAGE_SIZE
> > .code64
> >
> > .section ".bss.stack_aligned","w"
> > ENTRY(cpu0_stack)
> > .fill STACK_SIZE,1,0
> > ______________________________________________________
> > trying to understand that:
> >
> > - idle_pg_table_l4 is the same as idle_pg_table and contains
> > 263 enties,
> > all zeroed but two (identical) ones. These
> > two pointers point somewhere close to idle_pg_table_l3. Why are there
> > two identical pointers and why shift them by __PAGE_OFFSET +7?
>
> So that we can have a map for both LOW memory (address zero and 1GB
> forward) and a map for the upper range of memory where Xen's
> base-virtual address is (__PAGE_OFFSET). I think you'll find that if you
> shift __PAGE_OFFSET sufficient number of bits (30 or so), the remaining
> number is 262... [I haven't checked this]. Reusing the same-pagetable
> entry allows the use of a single entry in the next page-table level.
>
> It's shifted by PAGE_OFFSET because the code is linked such that
> everything is based on the virtual address that we eventually will use
> in the system. But the page-table wants to have a PHYSICAL address, so
> we subtract the virtual baseaddress from the location that we want the
> PT entry to point to.
>
> The magic number of 7 represents the flags for the page-entry, which is
> bit 0=Present, bit 1= R/W (Writable) and bit 2 U/S => User accessible.
> Since this is the top lavel page, it makes sense to set it all to
> present and allow full access, since next level down can always override
> a permission (but can't allow something forbidden by upper level).
>
> >
> > - idle_pg_table_l3 is located between 0x3000 and 0x4000 ,
> > with only the
> > first slot initialised. The later points to
> > level 2 table with some offset.
>
> This allows the next 128MB of memory to be mapped. Which is sufficient
> for the initialization of the system.
> >
> > - idle_pg_table_l2 has terrible code with a recursive macro,
> > who expands
> > into 63 quad constants. It is unclear
> > to me why this complicated macro?? I would have put a table
> > of constants
> > pretty simply... Every entry in that l2 table points to a
> > fixed address, at intervals of 4K (a page).l2 tables are
> > located between
> > 0x01E3 to 0x03E001E3 in groups. Every group
> > is apparently a set of 4 page tables and each table has a
> > size of 128K.
> > Groups are separated by approx 256MB.
> > Why are these spacings and groups?
>
> I can't explain why there is a macro and why it does things in the way
> it does, except I think you'll find that it's related to the code being
> located at a virtual address which is non-zero at this level [I haven't
> checked this out].
>
> The value 0x1E3 is used to indicate that the pages are 2MB, Dirty
> (prevents the MMU from rewriting them dirty if they are later written),
> Accessed (same reason as D), Writeable and Present.
> >
> > - idle_pg_table_l1 is not an entry and so l1 tables are not
> > allocated. Why?
>
> Because the value 1E3 (or part thereof) is indicating that the page is
> 2MB pages, so we don't need a L1 table entry for the pages defined in
> the above way.
>
> May I ask what you're trying to achieve - as far as I know, the above
> code is working just fine, so messing with it doesn't seem like a good
> plan [Getting page-table initialization and such things to work right is
> notoriously complicated, because it tends to break without any way of
> really debugging it].
>
> --
> Mats
The above was a lot of help for me and I'm sure many others. Thanks.
Do we have a good place in the xenwiki where this sort of low-level
initialization can be captured for future reference? Maybe another
entry in http://wiki.xensource.com/xenwiki/XenArchitecture ?
--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253 T/L: 678-9253
ryanh@xxxxxxxxxx
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|