diff -Nuar bak.linux-2.6.29.4-coloring/arch/x86/include/asm/pgtable_64.h linux-2.6.29.4-coloring/arch/x86/include/asm/pgtable_64.h
--- bak.linux-2.6.29.4-coloring/arch/x86/include/asm/pgtable_64.h 2011-01-19 21:02:18.095523974 +0800
+++ linux-2.6.29.4-coloring/arch/x86/include/asm/pgtable_64.h 2011-01-19 23:52:06.515523975 +0800
@@ -17,9 +17,10 @@
extern pud_t level3_ident_pgt[512];
extern pmd_t level2_kernel_pgt[512];
extern pmd_t level2_fixmap_pgt[512];
+extern pgd_t level1_fixmap_pgt[512];
extern pmd_t level2_ident_pgt[512];
extern pgd_t init_level4_pgt[];
-
+//extern pgd_t level2_spare_pgt[512];
#define swapper_pg_dir init_level4_pgt
extern void paging_init(void);
diff -Nuar bak.linux-2.6.29.4-coloring/arch/x86/kernel/setup.c linux-2.6.29.4-coloring/arch/x86/kernel/setup.c
--- bak.linux-2.6.29.4-coloring/arch/x86/kernel/setup.c 2011-01-19 21:02:18.275523974 +0800
+++ linux-2.6.29.4-coloring/arch/x86/kernel/setup.c 2011-02-20 16:11:28.973603962 +0800
@@ -842,6 +842,7 @@
#endif
/* max_pfn_mapped is updated here */
+ printk("@@:init_memory_mapping---[0,%08llx]\n", max_low_pfn<<PAGE_SHIFT);
max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
max_pfn_mapped = max_low_pfn_mapped;
diff -Nuar bak.linux-2.6.29.4-coloring/arch/x86/mm/init_64.c linux-2.6.29.4-coloring/arch/x86/mm/init_64.c
--- bak.linux-2.6.29.4-coloring/arch/x86/mm/init_64.c 2011-01-19 21:02:18.015523974 +0800
+++ linux-2.6.29.4-coloring/arch/x86/mm/init_64.c 2011-02-20 20:56:59.103603990 +0800
@@ -547,6 +547,124 @@
return phys_pud_init(pud, addr, end, page_size_mask);
}
+//remap kernel image
+
+#define assert(x) \
+ do { \
+ if (!(x)) { \
+ printk("assert failure: %s, %d, %s", __FILE__, __LINE__, #x); \
+ printk("BLOCK!!\n"); \
+ while (1) { \
+ } \
+ } \
+ } while (0)
+
+void
+set_kernel_pmd(pmd_t *pmd, unsigned long start, unsigned long end) {
+ assert((start & ~PMD_MASK) == 0);
+// assert(end == start + PMD_SIZE);
+// printk("%lx - %lx\n", start, end);
+ assert(sizeof(pte_t) == 8);
+ pte_t *pte = __get_free_page(GFP_KERNEL);
+ int i;
+ for (i = 0; i < PTRS_PER_PTE; i ++, start += PAGE_SIZE) {
+ unsigned long addr = __get_free_page(GFP_KERNEL);
+ memcpy((void *)addr, (void *)start, PAGE_SIZE);
+// printk("Before remap: %016llx -- %016llx.\n", start, __pa(start));
+ set_pte(&pte[i], pfn_pte(__pa(addr) >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
+// memcpy((void *)addr, (void *)start, PAGE_SIZE);
+// printk("After remap: %016llx -- %016llx.\n", start, pte_val(pte[i]) & PAGE_MASK);
+ }
+
+// assert(start == end);
+ spin_lock(&init_mm.page_table_lock);
+ set_pmd(pmd, __pmd(__pa(pte) | _PAGE_PRESENT | _PAGE_RW));
+
+ spin_unlock(&init_mm.page_table_lock);
+
+}
+
+unsigned long __meminit
+kernel_physical_remapping3(unsigned long start, unsigned long end)
+{
+ int i;
+ unsigned long *ptr;
+
+ unsigned long *__init_level4_pgt = get_zeroed_page(GFP_KERNEL);
+ memcpy((void *)__init_level4_pgt, (void *)init_level4_pgt, PAGE_SIZE);
+
+ unsigned long *__level3_ident_pgt = get_zeroed_page(GFP_KERNEL);
+ memcpy((void *)__level3_ident_pgt, (void *)level3_ident_pgt, PAGE_SIZE);
+
+ unsigned long *__level3_kernel_pgt = get_zeroed_page(GFP_KERNEL);
+ memcpy((void *)__level3_kernel_pgt, (void *)level3_kernel_pgt, PAGE_SIZE);
+
+ unsigned long *__level2_fixmap_pgt = get_zeroed_page(GFP_KERNEL);
+ memcpy((void *)__level2_fixmap_pgt, (void *)level2_fixmap_pgt, PAGE_SIZE);
+
+
+
+ unsigned long *__level1_fixmap_pgt = get_zeroed_page(GFP_KERNEL);
+ memcpy((void *)__level1_fixmap_pgt, (void *)level1_fixmap_pgt, PAGE_SIZE);
+
+ unsigned long *__level2_ident_pgt = get_zeroed_page(GFP_KERNEL);
+ memcpy((void *)__level2_ident_pgt, (void *)level2_ident_pgt, PAGE_SIZE);
+
+ unsigned long *__level2_kernel_pgt = get_zeroed_page(GFP_KERNEL);
+ memcpy((void *)__level2_kernel_pgt, (void *)level2_kernel_pgt, PAGE_SIZE);
+
+ unsigned long *__level2_spare_pgt = get_zeroed_page(GFP_KERNEL);
+// memcpy((void *)__level2_spare_pgt, (void *)level2_spare_pgt, PAGE_SIZE);
+
+ //set pgt: init_level4_pgt
+ ptr = (unsigned long *)__init_level4_pgt;
+ assert(sizeof(unsigned long) == 8);
+
+ set_pgd((pgd_t *)ptr, __pgd(_PAGE_TABLE | __pa(__level3_ident_pgt)));
+ set_pgd((pgd_t *)(ptr + pgd_index(PAGE_OFFSET)), __pgd(_PAGE_TABLE | __pa(__level3_ident_pgt)));
+ set_pgd((pgd_t *)(ptr + 511), __pgd(_PAGE_TABLE | __pa(__level3_kernel_pgt)));
+
+ //set pud: level3_ident_pgt
+ ptr = (unsigned long *)__level3_ident_pgt;
+ set_pud((pud_t *)ptr, __pud(_PAGE_TABLE | __pa(__level2_ident_pgt)));
+
+ //set pud: level3_kernel_pgt
+ ptr = (unsigned long *)__level3_kernel_pgt;
+ set_pud((pud_t *)(ptr + 510), __pud(_PAGE_TABLE | __pa(__level2_kernel_pgt)));
+ set_pud((pud_t *)(ptr + 511), __pud(_PAGE_TABLE | __pa(__level2_fixmap_pgt)));
+
+ //set pmd: level2_fixmap_pgt
+ ptr = (unsigned long *)__level2_fixmap_pgt;
+// set_pmd((pmd_t *)(ptr + 506), __pmd(_PAGE_TABLE | __pa(__level1_fixmap_pgt)));
+
+ //set pmd: level1_fixmap_pgt
+ //...
+
+ //set pmd: level2_ident_pgt
+ //...
+
+ //set_pmd: level2_kernel_pgt
+ ptr = (unsigned long *)__level2_kernel_pgt;
+ /** the first pmd is associated with 0-2M, the second pmd is associated with
+ [_text, _text + 2M], therefore, i starts from 1, not 0
+ */
+ for( i = 1; i < PTRS_PER_PMD && start < end; i++ ) {
+ printk("####PMD: %16lx\n", pmd_val(*((pmd_t *)(ptr + i))));
+ set_kernel_pmd((pmd_t *)(ptr + i), start, end);
+ printk("!!!!PMD: %16lx\n", pmd_val(*((pmd_t *)(ptr + i))));
+ start += PMD_SIZE;
+ }
+
+ //set_pmd: level2_spare_pgt
+ //...
+
+ load_cr3((pgd_t *)__init_level4_pgt);
+ __flush_tlb_all();
+
+ return 0;
+}
+
+
static void __init find_early_table_space(unsigned long end, int use_pse,
int use_gbpages)
{
diff -Nuar bak.linux-2.6.29.4-coloring/init/main.c linux-2.6.29.4-coloring/init/main.c
--- bak.linux-2.6.29.4-coloring/init/main.c 2011-01-19 21:02:32.275523975 +0800
+++ linux-2.6.29.4-coloring/init/main.c 2011-02-20 20:57:23.963604029 +0800
@@ -458,6 +458,7 @@
kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
unlock_kernel();
+
/*
* The boot idle thread must execute schedule()
* at least once to get things moving:
@@ -557,6 +558,8 @@
printk(KERN_NOTICE);
printk(linux_banner);
setup_arch(&command_line);
+
+
mm_init_owner(&init_mm, &init_task);
setup_command_line(command_line);
setup_per_cpu_areas();
@@ -673,6 +676,7 @@
proc_root_init();
#endif
cgroup_init();
+
cpuset_init();
taskstats_init_early();
delayacct_init();
@@ -683,6 +687,11 @@
ftrace_init();
+ //remap kernel image
+ unsigned long code_src = (char *)_text, code_src_end = (char *) _end;
+ extern unsigned long kernel_physical_remapping3(unsigned long , unsigned long);
+ kernel_physical_remapping3(code_src, code_src_end);
+
/* Do the rest non-__init'ed, we're now alive */
rest_init();
}
diff -Nuar bak.linux-2.6.29.4-coloring/kernel/printk.c linux-2.6.29.4-coloring/kernel/printk.c
--- bak.linux-2.6.29.4-coloring/kernel/printk.c 2011-01-19 21:02:32.065523975 +0800
+++ linux-2.6.29.4-coloring/kernel/printk.c 2011-01-19 21:44:01.515523976 +0800
@@ -621,6 +621,52 @@
static int new_text_line = 1;
static char printk_buf[1024];
+// for printing msg when booting immediately
+#define LPTPORT 0x378
+
+static inline uint8_t
+__inb(uint16_t port) {
+ uint8_t data;
+ asm volatile ("inb %1, %0" : "=a" (data) : "d" (port));
+ return data;
+}
+
+static inline void
+__outb(uint16_t port, uint8_t data) {
+ asm volatile ("outb %0, %1" :: "a" (data), "d" (port));
+}
+
+static void
+delay(void) {
+ __inb(0x84);
+ __inb(0x84);
+ __inb(0x84);
+ __inb(0x84);
+}
+
+static void
+lpt_putc_sub(int c) {
+ int i;
+ for (i = 0; !(__inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
+ delay();
+ }
+ __outb(LPTPORT + 0, c);
+ __outb(LPTPORT + 2, 0x08 | 0x04 | 0x01);
+ __outb(LPTPORT + 2, 0x08);
+}
+
+static void
+lpt_putc(int c) {
+ if (c != '\b') {
+ lpt_putc_sub(c);
+ }
+ else {
+ lpt_putc_sub('\b');
+ lpt_putc_sub(' ');
+ lpt_putc_sub('\b');
+ }
+}//end
+
asmlinkage int vprintk(const char *fmt, va_list args)
{
int printed_len = 0;
@@ -667,6 +713,11 @@
printed_len += vscnprintf(printk_buf + printed_len,
sizeof(printk_buf) - printed_len, fmt, args);
+ int i;
+ for (i = 0; i < printed_len; i ++) {
+ lpt_putc_sub(printk_buf[i]);
+ }
+
|