LKML Archive on lore.kernel.org
 help / color / Atom feed
* [i386] Questions regarding provisional page tables initialization
@ 2007-07-01 20:38 Ahmed S. Darwish
  2007-07-01 22:02 ` Andreas Schwab
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Ahmed S. Darwish @ 2007-07-01 20:38 UTC (permalink / raw)
  To: linux-kernel

Hi list,

AFAIK, in the initializaion phase, kernel builds pages tables with two
mappings, identity and PAGE_OFFSET + C mapping. The provisional _global
directory_ is contained in swapper_pg_dir variable. while the provisional 
_page tables_ are stored starting from pg0, right after _end.

There're some stuff that confused me for a full day about the code (head.S)
that  accomplishes the above words:

	movl $(pg0 - __PAGE_OFFSET), %edi
	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx	
	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
10:
	leal $0x007(%edi),%ecx			/* Create PDE entry */

What does the address of 7 bytes displacement after %edi - the physical address
of pg0 - represent ?. Why not just putting the address of %edi (the address of
pagetable cell to be mapped by swapper_pg_dir) in %ecx without displacement?

        page_pde_offset = (__PAGE_OFFSET >> 20)
	movl %ecx,(%edx)			/* Store identity PDE entry */
	movl %ecx,page_pde_offset(%edx)		/* Store kernel PDE entry */

Why the pde_offset is PAGE_OFFSET >> 20 instead of PAGE_OFFSET >> 22 ?
* 22 to right shift the whole page_shift (12) and pgdir_shift (10) bits.

        [...]
	/* Initialize the 1024 _page table_ cells with %eax (0x007) */
	movl $1024, %ecx
11:
	stosl
	addl $0x1000,%eax
	loop 11b

The page table entries beginning from pg0 (pointed by %edi) and following pages 
are initialized with  the series 7 + 8 + 8 + ... for each cell. This series has
the property of setting the PRESENT+RW+USER bits in the whole entries to 1 but it
sets lots of the entries BASE address to 0 too. Why is this done ?

Thanks,

-- 
Ahmed S. Darwish
HomePage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-01 20:38 [i386] Questions regarding provisional page tables initialization Ahmed S. Darwish
@ 2007-07-01 22:02 ` Andreas Schwab
  2007-07-01 22:19 ` Jeremy Fitzhardinge
  2007-07-02 10:43 ` Andi Kleen
  2 siblings, 0 replies; 9+ messages in thread
From: Andreas Schwab @ 2007-07-01 22:02 UTC (permalink / raw)
  To: Ahmed S. Darwish; +Cc: linux-kernel

"Ahmed S. Darwish" <darwish.07@gmail.com> writes:

>         page_pde_offset = (__PAGE_OFFSET >> 20)
> 	movl %ecx,(%edx)			/* Store identity PDE entry */
> 	movl %ecx,page_pde_offset(%edx)		/* Store kernel PDE entry */
>
> Why the pde_offset is PAGE_OFFSET >> 20 instead of PAGE_OFFSET >> 22 ?
> * 22 to right shift the whole page_shift (12) and pgdir_shift (10) bits.

4 is the element size.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-01 20:38 [i386] Questions regarding provisional page tables initialization Ahmed S. Darwish
  2007-07-01 22:02 ` Andreas Schwab
@ 2007-07-01 22:19 ` Jeremy Fitzhardinge
  2007-07-02  1:13   ` Ahmed S. Darwish
  2007-07-02 10:43 ` Andi Kleen
  2 siblings, 1 reply; 9+ messages in thread
From: Jeremy Fitzhardinge @ 2007-07-01 22:19 UTC (permalink / raw)
  To: Ahmed S. Darwish; +Cc: linux-kernel

Ahmed S. Darwish wrote:
> Hi list,
>
> AFAIK, in the initializaion phase, kernel builds pages tables with two
> mappings, identity and PAGE_OFFSET + C mapping. The provisional _global
> directory_ is contained in swapper_pg_dir variable. while the provisional 
> _page tables_ are stored starting from pg0, right after _end.
>
> There're some stuff that confused me for a full day about the code (head.S)
> that  accomplishes the above words:
>
> 	movl $(pg0 - __PAGE_OFFSET), %edi
> 	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx	
> 	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
> 10:
> 	leal $0x007(%edi),%ecx			/* Create PDE entry */
>
> What does the address of 7 bytes displacement after %edi - the physical address
> of pg0 - represent ?. Why not just putting the address of %edi (the address of
> pagetable cell to be mapped by swapper_pg_dir) in %ecx without displacement?
>   

The pte format contains the pfn in the top 20 bits, and flags in the 
lower 12 bits.  As the comment says "0x007 = PRESENT+RW+USER".

>         page_pde_offset = (__PAGE_OFFSET >> 20)
> 	movl %ecx,(%edx)			/* Store identity PDE entry */
> 	movl %ecx,page_pde_offset(%edx)		/* Store kernel PDE entry */
>
> Why the pde_offset is PAGE_OFFSET >> 20 instead of PAGE_OFFSET >> 22 ?
> * 22 to right shift the whole page_shift (12) and pgdir_shift (10) bits.
>   

As Andreas said, its (PAGE_OFFSET >> 22) << 2.

>         [...]
> 	/* Initialize the 1024 _page table_ cells with %eax (0x007) */
> 	movl $1024, %ecx
> 11:
> 	stosl
> 	addl $0x1000,%eax
> 	loop 11b
>
> The page table entries beginning from pg0 (pointed by %edi) and following pages 
> are initialized with  the series 7 + 8 + 8 + ... for each cell. This series has
> the property of setting the PRESENT+RW+USER bits in the whole entries to 1 but it
> sets lots of the entries BASE address to 0 too. Why is this done ?
>   

I don't follow you.  Are you overlooking the 'L' on stosl?

    J

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-01 22:19 ` Jeremy Fitzhardinge
@ 2007-07-02  1:13   ` Ahmed S. Darwish
  2007-07-02  9:18     ` Andreas Schwab
  0 siblings, 1 reply; 9+ messages in thread
From: Ahmed S. Darwish @ 2007-07-02  1:13 UTC (permalink / raw)
  To: Jeremy Fitzhardinge; +Cc: linux-kernel

Hi Jeremy,

On Sun, Jul 01, 2007 at 03:19:30PM -0700, Jeremy Fitzhardinge wrote:
> Ahmed S. Darwish wrote:
> >Hi list,
> >
> >AFAIK, in the initializaion phase, kernel builds pages tables with two
> >mappings, identity and PAGE_OFFSET + C mapping. The provisional _global
> >directory_ is contained in swapper_pg_dir variable. while the provisional 
> >_page tables_ are stored starting from pg0, right after _end.
> >
> >There're some stuff that confused me for a full day about the code (head.S)
> >that  accomplishes the above words:
> >
> >	movl $(pg0 - __PAGE_OFFSET), %edi
> >	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx	
> >	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
> >10:
> >	leal $0x007(%edi),%ecx			/* Create PDE entry */
> >
> >What does the address of 7 bytes displacement after %edi - the physical 
> >address
> >of pg0 - represent ?. Why not just putting the address of %edi (the 
> >address of
> >pagetable cell to be mapped by swapper_pg_dir) in %ecx without 
> >displacement?
> >  
> 
> The pte format contains the pfn in the top 20 bits, and flags in the 
> lower 12 bits.  As the comment says "0x007 = PRESENT+RW+USER".
> 

yes, but isn't the displacement here (0x007) a _bytes_ displacement ?. so
effectively, %ecx now contains physical address of pg0 + 7bytes. Is it A 
meaningful place/address ?.

> >        page_pde_offset = (__PAGE_OFFSET >> 20)
> >	movl %ecx,(%edx)			/* Store identity PDE entry 
> >	*/
> >	movl %ecx,page_pde_offset(%edx)		/* Store kernel PDE entry */
> >
> >Why the pde_offset is PAGE_OFFSET >> 20 instead of PAGE_OFFSET >> 22 ?
> >* 22 to right shift the whole page_shift (12) and pgdir_shift (10) bits.
> >  
> 
> As Andreas said, its (PAGE_OFFSET >> 22) << 2.
> 

Great!, Thanks a lot.

> >        [...]
> >	/* Initialize the 1024 _page table_ cells with %eax (0x007) */
> >	movl $1024, %ecx
> >11:
> >	stosl
> >	addl $0x1000,%eax
> >	loop 11b
> >
> >The page table entries beginning from pg0 (pointed by %edi) and following 
> >pages are initialized with  the series 7 + 8 + 8 + ... for each cell. This 
> >series has
> >the property of setting the PRESENT+RW+USER bits in the whole entries to 1 
> >but it
> >sets lots of the entries BASE address to 0 too. Why is this done ?
> >  
> 
> I don't follow you.  Are you overlooking the 'L' on stosl?
> 

Sorry for not making the question clear. my question was that the first entry in
the page table pointed by (%edi) is initialize with %eax = 0x007, a reasonable
value (setting the 3 pte flags). Beginning from entry 2, they got initialized
with a value = "new %eax = old %eax + 8", generating a table of entries
initialized with 7, 15, 31, .. . While this scheme makes the 3 PRESENT, RW 
and USER flags set, it makes alot of "pte"s with equivalent "pfn"s. Here comes 
my wonder, why initializing pg0 that way ?.

Thanks,

-- 
Ahmed S. Darwish
HomePage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-02  1:13   ` Ahmed S. Darwish
@ 2007-07-02  9:18     ` Andreas Schwab
  2007-07-02 10:23       ` Ahmed S. Darwish
  0 siblings, 1 reply; 9+ messages in thread
From: Andreas Schwab @ 2007-07-02  9:18 UTC (permalink / raw)
  To: Ahmed S. Darwish; +Cc: Jeremy Fitzhardinge, linux-kernel

"Ahmed S. Darwish" <darwish.07@gmail.com> writes:

> yes, but isn't the displacement here (0x007) a _bytes_ displacement ?. so
> effectively, %ecx now contains physical address of pg0 + 7bytes. Is it A 
> meaningful place/address ?.

It's not pg0 + 7bytes, it is pg0 plus 3 flag bits.  Since a page address
is always page aligned, the low bits are reused for flags.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-02  9:18     ` Andreas Schwab
@ 2007-07-02 10:23       ` Ahmed S. Darwish
  2007-07-02 11:34         ` Brian Gerst
  0 siblings, 1 reply; 9+ messages in thread
From: Ahmed S. Darwish @ 2007-07-02 10:23 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jeremy Fitzhardinge, linux-kernel

Hi Andreas,

On Mon, Jul 02, 2007 at 11:18:08AM +0200, Andreas Schwab wrote:
> "Ahmed S. Darwish" <darwish.07@gmail.com> writes:
> 
> > yes, but isn't the displacement here (0x007) a _bytes_ displacement ?. so
> > effectively, %ecx now contains physical address of pg0 + 7bytes. Is it A 
> > meaningful place/address ?.
> 
> It's not pg0 + 7bytes, it is pg0 plus 3 flag bits.  Since a page address
> is always page aligned, the low bits are reused for flags.
> 

I'm sure there's a problem in _my_ understanding, but isn't the displacement
- as specified by AT&T syntax - represented in bytes ?. I've wrote a small
assembly function to be sure:

.data
integer:
	.string "%d\n"

.text
test_func:
	push	%ebp
	mov	%esp, %ebp
	push	0x008(%ebp)   ## 8 bytes displacement (the first arg), right ?
	push	$integer
	call 	printf
	mov	%ebp, %esp
	pop	%ebp
	ret

The above method works fine and prints "5" to stdout by the code:

.global	main
main:
	mov	$5, %eax
	push	%eax
	call	test_func

	movl	$1, %eax
	movl	$0, %ebx
	int	$0x80

now back to head.S code:
 	leal    0x007(%edi),%ecx	/* Create PDE entry */

Isn't the above line the same condition (bytes, not bits displacement) ?. 
Thanks for your patience !.

(For other kind replies, don't understand me wrong. I did my homework and
 studied the pte format before asking ;). It's just the bytes/bits issue 
 above that confuses me).

-- 
Ahmed S. Darwish
HomePage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-01 20:38 [i386] Questions regarding provisional page tables initialization Ahmed S. Darwish
  2007-07-01 22:02 ` Andreas Schwab
  2007-07-01 22:19 ` Jeremy Fitzhardinge
@ 2007-07-02 10:43 ` Andi Kleen
  2 siblings, 0 replies; 9+ messages in thread
From: Andi Kleen @ 2007-07-02 10:43 UTC (permalink / raw)
  To: Ahmed S. Darwish; +Cc: linux-kernel

"Ahmed S. Darwish" <darwish.07@gmail.com> writes:
> 
> There're some stuff that confused me for a full day about the code (head.S)
> that  accomplishes the above words:
> 
> 	movl $(pg0 - __PAGE_OFFSET), %edi
> 	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx	
> 	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
> 10:
> 	leal $0x007(%edi),%ecx			/* Create PDE entry */
> 
> What does the address of 7 bytes displacement after %edi - the physical address
> of pg0 - represent ?. 

The trick is not to know everything, but to know where to look ...

Page table entries use the first 12 bits for various flags. Take a look
at the Intel or AMD x86 documentation from their websites.

-Andi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-02 10:23       ` Ahmed S. Darwish
@ 2007-07-02 11:34         ` Brian Gerst
  2007-07-02 15:43           ` Ahmed S. Darwish
  0 siblings, 1 reply; 9+ messages in thread
From: Brian Gerst @ 2007-07-02 11:34 UTC (permalink / raw)
  To: Ahmed S. Darwish; +Cc: Andreas Schwab, Jeremy Fitzhardinge, linux-kernel

Ahmed S. Darwish wrote:
> now back to head.S code:
>  	leal    0x007(%edi),%ecx	/* Create PDE entry */
> 
> Isn't the above line the same condition (bytes, not bits displacement) ?. 
> Thanks for your patience !.

The leal instruction (Load Effective Address) is often used as a way to
add a constant to one register and store the result in another register
in a single instruction.  The values don't even have to be addresses at
all, since no memory is actually referenced.  Otherwise this would be
written as:

	movl %edi,%ecx
	addl $0x007, %ecx

--
				Brian Gerst

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [i386] Questions regarding provisional page tables initialization
  2007-07-02 11:34         ` Brian Gerst
@ 2007-07-02 15:43           ` Ahmed S. Darwish
  0 siblings, 0 replies; 9+ messages in thread
From: Ahmed S. Darwish @ 2007-07-02 15:43 UTC (permalink / raw)
  To: Brian Gerst; +Cc: Andreas Schwab, Jeremy Fitzhardinge, linux-kernel

On Mon, Jul 02, 2007 at 07:34:20AM -0400, Brian Gerst wrote:
> Ahmed S. Darwish wrote:
> > now back to head.S code:
> >  	leal    0x007(%edi),%ecx	/* Create PDE entry */
> > 
> > Isn't the above line the same condition (bytes, not bits displacement) ?. 
> > Thanks for your patience !.
> 
> The leal instruction (Load Effective Address) is often used as a way to
> add a constant to one register and store the result in another register
> in a single instruction.
> [...]

At last I got it due to all of everybody's very nice explanations :). 
Here's the provisional page tables intialization scenario:

We want to store pg0 pte addresses to high 20bits swapper_pg_dir entries,
we also want the PRESENT,RW,USER flags be set in those entries. This is 
done by  getting the address of each pg0 entry and adding 7 to it (Brian's
note). Since pg0 entires address are page aligned(Andreas, Jeremy notes),
adding 7 will assure that the first 3 bits are set without affecting the
high 20 bits.

Big Thanks!,

-- 
Ahmed S. Darwish
HomePage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, back to index

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-01 20:38 [i386] Questions regarding provisional page tables initialization Ahmed S. Darwish
2007-07-01 22:02 ` Andreas Schwab
2007-07-01 22:19 ` Jeremy Fitzhardinge
2007-07-02  1:13   ` Ahmed S. Darwish
2007-07-02  9:18     ` Andreas Schwab
2007-07-02 10:23       ` Ahmed S. Darwish
2007-07-02 11:34         ` Brian Gerst
2007-07-02 15:43           ` Ahmed S. Darwish
2007-07-02 10:43 ` Andi Kleen

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lkml.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lkml.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lkml.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lkml.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lkml.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lkml.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lkml.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lkml.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lkml.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lkml.kernel.org/lkml/9 lkml/git/9.git
	git clone --mirror https://lkml.kernel.org/lkml/10 lkml/git/10.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lkml.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git