]> git.zerfleddert.de Git - ms2-kexec/commitdiff
A bit of a success :-)
authorMichael Gernoth <michael@gernoth.net>
Tue, 24 May 2011 20:19:01 +0000 (22:19 +0200)
committerMichael Gernoth <michael@gernoth.net>
Tue, 24 May 2011 20:19:01 +0000 (22:19 +0200)
The module is now able to load a kernel and extract it, when run on
a beagle-board. But the extracted kernel won't boot :-(

Makefile
idmap.c
machine_kexec.c
mmu.c
proc-v7.S
relocate_kernel.S
sys.c
tlbflush.h

index bc86aacceea162bea18192afa5620bb63a0d32d4..aea8202e7ddd1872555c3f441651d6cdab17878b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ CROSS_PATH=$(PWD)/../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin
 EXTRA_CFLAGS += -DCONFIG_KEXEC -Wall
 
 obj-m += kexec_load.o
 EXTRA_CFLAGS += -DCONFIG_KEXEC -Wall
 
 obj-m += kexec_load.o
-kexec_load-objs := kexec.o machine_kexec.o idmap.o sys.o core.o relocate_kernel.o \
+kexec_load-objs := kexec.o machine_kexec.o mmu.o sys.o core.o relocate_kernel.o \
        proc-v7.o tlb-v7.o cache-v7.o abort-ev7.o pabort-v7.o copypage-v6.o driver_sys.o
 
 all:
        proc-v7.o tlb-v7.o cache-v7.o abort-ev7.o pabort-v7.o copypage-v6.o driver_sys.o
 
 all:
diff --git a/idmap.c b/idmap.c
index e667f7446da08557f5bd33f5c4441e791c033b68..c108a73f33b7f8e2df26631cb54c96e2752e4c5f 100644 (file)
--- a/idmap.c
+++ b/idmap.c
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 
 #include <linux/kernel.h>
 
+#include "tlbflush.h"
 #include <asm/cputype.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/cputype.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
@@ -88,5 +89,5 @@ void setup_mm_for_reboot(char mode)
         * "borrowed".
         */
        identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
         * "borrowed".
         */
        identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
-       local_flush_tlb_all();
+       my_local_flush_tlb_all();
 }
 }
index e38af78492d4fed325055f3ee0167aed838ec777..9157d4c4ab21bb8bcc33429458dc4855ea17a8c2 100644 (file)
@@ -18,6 +18,8 @@ extern const unsigned int relocate_new_kernel_size;
 
 extern void setup_mm_for_reboot(char mode);
 
 
 extern void setup_mm_for_reboot(char mode);
 
+extern void v7_flush_kern_cache_all(void);
+
 extern unsigned long kexec_start_address;
 extern unsigned long kexec_indirection_page;
 extern unsigned long kexec_mach_type;
 extern unsigned long kexec_start_address;
 extern unsigned long kexec_indirection_page;
 extern unsigned long kexec_mach_type;
@@ -47,7 +49,7 @@ void machine_crash_nonpanic_core(void *unused)
        printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
               smp_processor_id());
        crash_save_cpu(&regs, smp_processor_id());
        printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
               smp_processor_id());
        crash_save_cpu(&regs, smp_processor_id());
-       flush_cache_all();
+       v7_flush_kern_cache_all();
 
        atomic_dec(&waiting_for_crash_ipi);
        while (1)
 
        atomic_dec(&waiting_for_crash_ipi);
        while (1)
@@ -86,7 +88,6 @@ void machine_kexec(struct kimage *image)
        unsigned long reboot_code_buffer_phys;
        void *reboot_code_buffer;
 
        unsigned long reboot_code_buffer_phys;
        void *reboot_code_buffer;
 
-
        page_list = image->head & PAGE_MASK;
 
        /* we need both effective and real address here */
        page_list = image->head & PAGE_MASK;
 
        /* we need both effective and real address here */
@@ -114,7 +115,7 @@ void machine_kexec(struct kimage *image)
        local_irq_disable();
        local_fiq_disable();
        setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
        local_irq_disable();
        local_fiq_disable();
        setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
-       flush_cache_all();
+       v7_flush_kern_cache_all();
 #ifdef CONFIG_OUTER_CACHE
        outer_flush_all();
        outer_disable();
 #ifdef CONFIG_OUTER_CACHE
        outer_flush_all();
        outer_disable();
@@ -123,6 +124,6 @@ void machine_kexec(struct kimage *image)
 #ifdef CONFIG_OUTER_CACHE
        outer_inv_all();
 #endif
 #ifdef CONFIG_OUTER_CACHE
        outer_inv_all();
 #endif
-       flush_cache_all();
+       //v7_flush_kern_cache_all();
        cpu_reset(reboot_code_buffer_phys);
 }
        cpu_reset(reboot_code_buffer_phys);
 }
diff --git a/mmu.c b/mmu.c
index 7d25e1673b5de92a6c6a0bcf01ca5c7392925529..f58a7bdb01b0bf20ffb2818d3fb73b67a8e0c80c 100644 (file)
--- a/mmu.c
+++ b/mmu.c
@@ -17,6 +17,7 @@
 #include <linux/nodemask.h>
 #include <linux/ioport.h>
 
 #include <linux/nodemask.h>
 #include <linux/ioport.h>
 
+#include "tlbflush.h"
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
 #include <asm/sections.h>
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -41,19 +42,7 @@ void setup_mm_for_reboot(char mode)
        pgd_t *pgd;
        int i;
 
        pgd_t *pgd;
        int i;
 
-       if (current->mm && current->mm->pgd)
-               pgd = current->mm->pgd;
-#if 0
-       else
-               pgd = init_mm.pgd;
-#else
-       else
-       {
-               struct mm_struct *initmm = (struct mm_struct *)0xc05672a0;
-               pgd = initmm->pgd;
-       }
-#warning FIXME init_mm is no longer exported
-#endif
+       pgd = current->mm->pgd;
 
        base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
 
 
        base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
 
@@ -66,4 +55,5 @@ void setup_mm_for_reboot(char mode)
                pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
                flush_pmd_entry(pmd);
        }
                pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
                flush_pmd_entry(pmd);
        }
+       my_local_flush_tlb_all();
 }
 }
index 402ec2b11aa86b59ed93b89a32324ed57e349e59..fe7ffedc40c35d4d4281fc50e0271c76ed34230c 100644 (file)
--- a/proc-v7.S
+++ b/proc-v7.S
@@ -43,10 +43,14 @@ ENTRY(cpu_v7_proc_init)
 ENDPROC(cpu_v7_proc_init)
 
 ENTRY(cpu_v7_proc_fin)
 ENDPROC(cpu_v7_proc_init)
 
 ENTRY(cpu_v7_proc_fin)
+       stmfd   sp!, {lr}
+       bl      v7_flush_kern_cache_all
        mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
        bic     r0, r0, #0x1000                 @ ...i............
        bic     r0, r0, #0x0006                 @ .............ca.
        mcr     p15, 0, r0, c1, c0, 0           @ disable caches
        mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
        bic     r0, r0, #0x1000                 @ ...i............
        bic     r0, r0, #0x0006                 @ .............ca.
        mcr     p15, 0, r0, c1, c0, 0           @ disable caches
+       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
+       ldmfd   sp!, {pc}
        mov     pc, lr
 ENDPROC(cpu_v7_proc_fin)
 
        mov     pc, lr
 ENDPROC(cpu_v7_proc_fin)
 
index 9cf4cbf8f95b8ca9eef1baf1d8f49054999304f8..f2b786811fb3893cbd9540b035424d35147bfdcc 100644 (file)
@@ -6,6 +6,15 @@
 
        .globl relocate_new_kernel
 relocate_new_kernel:
 
        .globl relocate_new_kernel
 relocate_new_kernel:
+       /* Disable MMU */
+       mov     ip, #0
+#ifdef CONFIG_MMU
+       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
+#endif
+       mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
+       bic     ip, ip, #0x000f                 @ ............wcam
+       bic     ip, ip, #0x1100                 @ ...i...s........
+       mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
 
        ldr     r0,kexec_indirection_page
        ldr     r1,kexec_start_address
 
        ldr     r0,kexec_indirection_page
        ldr     r1,kexec_start_address
diff --git a/sys.c b/sys.c
index 611276bf10882c9f23704d02835fec9c0b88dc66..23eb124f3cb40c1931dc6de2bcded082a39aa124 100644 (file)
--- a/sys.c
+++ b/sys.c
@@ -63,8 +63,8 @@ void kernel_restart_prepare(char *cmd)
 
        blocking_notifier_call_chain(&notifier_head, SYS_RESTART, cmd);
        system_state = SYSTEM_RESTART;
 
        blocking_notifier_call_chain(&notifier_head, SYS_RESTART, cmd);
        system_state = SYSTEM_RESTART;
-//     device_shutdown();
-//     sysdev_shutdown();
+       //device_shutdown();
+       //sysdev_shutdown();
 }
 
 /*
 }
 
 /*
index d2005de383b8c105cf85368a5a7539bdaae0410b..51de99851872fea834194037df774e3e031e1f7e 100644 (file)
@@ -322,7 +322,7 @@ extern struct cpu_tlb_fns cpu_tlb;
 
 #define tlb_flag(f)    ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
 
 
 #define tlb_flag(f)    ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
 
-static inline void local_flush_tlb_all(void)
+static inline void my_local_flush_tlb_all(void)
 {
        const int zero = 0;
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 {
        const int zero = 0;
        const unsigned int __tlb_flag = __cpu_tlb_flags;
Impressum, Datenschutz