Chinaunix首页 | 论坛 | 博客
  • 博客访问: 439492
  • 博文数量: 123
  • 博客积分: 2686
  • 博客等级: 少校
  • 技术积分: 1349
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-23 22:11
文章分类
文章存档

2012年(3)

2011年(10)

2010年(100)

2009年(10)

我的朋友

分类: LINUX

2011-02-21 09:55:51

 

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]);
+     }
+
 
     


阅读(1455) | 评论(1) | 转发(0) |
0

上一篇:Virtual Machine Monitor

下一篇:Understand Qemu

给主人留下些什么吧!~~

chinaunix网友2011-03-05 13:25:16

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com