public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] IA32 move PG0 page table within kernel data segment
@ 2006-10-09  5:48 bibo,mao
  2006-10-16 14:04 ` Andi Kleen
  0 siblings, 1 reply; 2+ messages in thread
From: bibo,mao @ 2006-10-09  5:48 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

Hi,
  On i386 kernel image can compile and run at any physical address,kernel
will dynamically establish initial page table at PG0. Currently PG0 address
is adjacent to _end, that is to say PG0 page table is out of kernel data segment.
 Some bootloader put initrd image next kernel data segment so that initial
page table will overwrite initrd imagte. This patch modify this and put PG0
table at BSS segment and free this space later.
  This patch limited kernel image size within 64M, it is possible to modify
ld script to remove this limit, but I am not familiar with ld script.

 Any comments is welcome.

 Signed-off-by: bibo, mao <bibo.mao@intel.com>

Thanks
bibo,mao 


diff -Nrup -X 2.6.18-mm3.org/Documentation/dontdiff 2.6.18-mm3.org/arch/i386/kernel/head.S 2.6.18-mm3/arch/i386/kernel/head.S
--- 2.6.18-mm3.org/arch/i386/kernel/head.S	2006-10-08 16:10:31.000000000 +0800
+++ 2.6.18-mm3/arch/i386/kernel/head.S	2006-10-09 09:14:57.000000000 +0800
@@ -43,8 +43,6 @@
  *
  * This should be a multiple of a page.
  */
-#define INIT_MAP_BEYOND_END	(128*1024)
-
 
 /*
  * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
@@ -105,10 +103,10 @@ ENTRY(startup_32)
 
 /*
  * Initialize page tables.  This creates a PDE and a set of page
- * tables, which are located immediately beyond _end.  The variable
+ * tables, which are located at pg0.  The variable
  * init_pg_tables_end is set up to point to the first "safe" location.
  * Mappings are created both at virtual address 0 (identity mapping)
- * and PAGE_OFFSET for up to _end+sizeof(page tables)+INIT_MAP_BEYOND_END.
+ * and PAGE_OFFSET for up to _end.
  *
  * Warning: don't use %esi or the stack in this code.  However, %esp
  * can be used as a GPR if you really need it...
@@ -117,6 +115,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
 
 	movl $(pg0 - __PAGE_OFFSET), %edi
 	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
+	movl $(_end - __PAGE_OFFSET),%ebx 
 	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
 10:
 	leal 0x007(%edi),%ecx			/* Create PDE entry */
@@ -128,12 +127,10 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
 	stosl
 	addl $0x1000,%eax
 	loop 11b
-	/* End condition: we must map up to and including INIT_MAP_BEYOND_END */
-	/* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
-	leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
-	cmpl %ebp,%eax
+	/* End condition: we must map up to _end address */
+	cmpl %ebx ,%edi
 	jb 10b
-	movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
+	movl %ebx, (init_pg_tables_end - __PAGE_OFFSET)
 
 #ifdef CONFIG_SMP
 	xorl %ebx,%ebx				/* This is the boot CPU (BSP) */
diff -Nrup -X 2.6.18-mm3.org/Documentation/dontdiff 2.6.18-mm3.org/arch/i386/kernel/vmlinux.lds.S 2.6.18-mm3/arch/i386/kernel/vmlinux.lds.S
--- 2.6.18-mm3.org/arch/i386/kernel/vmlinux.lds.S	2006-10-08 16:10:31.000000000 +0800
+++ 2.6.18-mm3/arch/i386/kernel/vmlinux.lds.S	2006-10-09 13:10:52.000000000 +0800
@@ -180,11 +180,15 @@ SECTIONS
   . = ALIGN(4);
   __bss_stop = .; 
 
-  _end = . ;
-
   /* This is where the kernel creates the early boot page tables */
   . = ALIGN(4096);
   pg0 = .;
+  .bss.pg : AT(ADDR(.bss.pg) - LOAD_OFFSET) {
+	. += (phys_startup_32 >> 10) + 0x10000;
+	. = ALIGN(4096);
+  }
+  pg_end = .;
+  _end = . ;
 
   /* Sections to be discarded */
   /DISCARD/ : {
diff -Nrup -X 2.6.18-mm3.org/Documentation/dontdiff 2.6.18-mm3.org/arch/i386/mm/init.c 2.6.18-mm3/arch/i386/mm/init.c
--- 2.6.18-mm3.org/arch/i386/mm/init.c	2006-10-08 16:10:31.000000000 +0800
+++ 2.6.18-mm3/arch/i386/mm/init.c	2006-10-08 15:52:12.000000000 +0800
@@ -793,6 +793,9 @@ void free_initmem(void)
 	free_init_pages("unused kernel memory",
 			(unsigned long)(&__init_begin),
 			(unsigned long)(&__init_end));
+	free_init_pages("initial page table",
+			(unsigned long)(&pg0),
+			(unsigned long)(&pg_end));
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff -Nrup -X 2.6.18-mm3.org/Documentation/dontdiff 2.6.18-mm3.org/include/asm-i386/pgtable.h 2.6.18-mm3/include/asm-i386/pgtable.h
--- 2.6.18-mm3.org/include/asm-i386/pgtable.h	2006-10-08 16:10:34.000000000 +0800
+++ 2.6.18-mm3/include/asm-i386/pgtable.h	2006-10-08 15:45:14.000000000 +0800
@@ -201,6 +201,7 @@ extern unsigned long long __PAGE_KERNEL,
 
 /* The boot page tables (all created as a single array) */
 extern unsigned long pg0[];
+extern unsigned long pg_end[];
 
 #define pte_present(x)	((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
 

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

end of thread, other threads:[~2006-10-16 14:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-09  5:48 [PATCH] IA32 move PG0 page table within kernel data segment bibo,mao
2006-10-16 14:04 ` Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox