patch-2.0.21-2.1.0 linux/arch/i386/mm/init.c

Next file: linux/arch/i386/mm/ioremap.c
Previous file: linux/arch/i386/mm/fault.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file lx2.0/v2.0.21/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
@@ -81,7 +81,7 @@
 	printk("Mem-info:\n");
 	show_free_areas();
 	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
-	i = high_memory >> PAGE_SHIFT;
+	i = max_mapnr;
 	while (i-- > 0) {
 		total++;
 		if (PageReserved(mem_map+i))
@@ -149,8 +149,10 @@
 	wp_works_ok = 0;
 #endif
 	start_mem = PAGE_ALIGN(start_mem);
-	address = 0;
+	address = PAGE_OFFSET;
 	pg_dir = swapper_pg_dir;
+	/* unmap the original low memory mappings */
+	pgd_val(pg_dir[0]) = 0;
 	while (address < end_mem) {
 #ifdef USE_PENTIUM_MM
 		/*
@@ -172,29 +174,29 @@
 				: : :"ax");
 #endif
 			wp_works_ok = 1;
-			pgd_val(pg_dir[0]) = _PAGE_TABLE | _PAGE_4M | address;
-			pgd_val(pg_dir[768]) = _PAGE_TABLE | _PAGE_4M | address;
+			pgd_val(pg_dir[768]) = _PAGE_TABLE + _PAGE_4M + __pa(address);
 			pg_dir++;
 			address += 4*1024*1024;
 			continue;
 		}
 #endif
 		/* map the memory at virtual addr 0xC0000000 */
+		/* pg_table is physical at this point */
 		pg_table = (pte_t *) (PAGE_MASK & pgd_val(pg_dir[768]));
 		if (!pg_table) {
-			pg_table = (pte_t *) start_mem;
+			pg_table = (pte_t *) __pa(start_mem);
 			start_mem += PAGE_SIZE;
 		}
 
-		/* also map it temporarily at 0x0000000 for init */
-		pgd_val(pg_dir[0])   = _PAGE_TABLE | (unsigned long) pg_table;
 		pgd_val(pg_dir[768]) = _PAGE_TABLE | (unsigned long) pg_table;
 		pg_dir++;
+		/* now change pg_table to kernel virtual addresses */
+		pg_table = (pte_t *) __va(pg_table);
 		for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
-			if (address < end_mem)
-				set_pte(pg_table, mk_pte(address, PAGE_SHARED));
-			else
-				pte_clear(pg_table);
+			pte_t pte = mk_pte(address, PAGE_KERNEL);
+			if (address >= end_mem)
+				pte_val(pte) = 0;
+			set_pte(pg_table, pte);
 			address += PAGE_SIZE;
 		}
 	}
@@ -212,13 +214,14 @@
 	extern int _etext;
 
 	end_mem &= PAGE_MASK;
-	high_memory = end_mem;
+	high_memory = (void *) end_mem;
+	max_mapnr = MAP_NR(end_mem);
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
 
 	/* mark usable pages in the mem_map[] */
-	start_low_mem = PAGE_ALIGN(start_low_mem);
+	start_low_mem = PAGE_ALIGN(start_low_mem)+PAGE_OFFSET;
 
 #ifdef __SMP__
 	/*
@@ -234,20 +237,20 @@
 	 * They seem to have done something stupid with the floppy
 	 * controller as well..
 	 */
-	while (start_low_mem < 0x9f000) {
+	while (start_low_mem < 0x9f000+PAGE_OFFSET) {
 		clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags);
 		start_low_mem += PAGE_SIZE;
 	}
 
-	while (start_mem < high_memory) {
+	while (start_mem < end_mem) {
 		clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
 		start_mem += PAGE_SIZE;
 	}
-	for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
+	for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
 		if (tmp >= MAX_DMA_ADDRESS)
 			clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
 		if (PageReserved(mem_map+MAP_NR(tmp))) {
-			if (tmp >= 0xA0000 && tmp < 0x100000)
+			if (tmp >= 0xA0000+PAGE_OFFSET && tmp < 0x100000+PAGE_OFFSET)
 				reservedpages++;
 			else if (tmp < (unsigned long) &_etext)
 				codepages++;
@@ -262,19 +265,24 @@
 #endif
 			free_page(tmp);
 	}
-	tmp = nr_free_pages << PAGE_SHIFT;
 	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
-		tmp >> 10,
-		high_memory >> 10,
+		(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+		max_mapnr << (PAGE_SHIFT-10),
 		codepages << (PAGE_SHIFT-10),
 		reservedpages << (PAGE_SHIFT-10),
 		datapages << (PAGE_SHIFT-10));
 /* test if the WP bit is honoured in supervisor mode */
 	if (wp_works_ok < 0) {
-		pg0[0] = pte_val(mk_pte(0, PAGE_READONLY));
+		unsigned char tmp_reg;
+		pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_READONLY));
 		local_flush_tlb();
-		__asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
-		pg0[0] = 0;
+		__asm__ __volatile__(
+			"movb %0,%1 ; movb %1,%0"
+			:"=m" (*(char *) __va(0)),
+			 "=q" (tmp_reg)
+			:/* no inputs */
+			:"memory");
+		pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_KERNEL));
 		local_flush_tlb();
 		if (wp_works_ok < 0)
 			wp_works_ok = 0;
@@ -286,7 +294,7 @@
 {
 	int i;
 
-	i = high_memory >> PAGE_SHIFT;
+	i = max_mapnr;
 	val->totalram = 0;
 	val->sharedram = 0;
 	val->freeram = nr_free_pages << PAGE_SHIFT;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov