From: Michael Gernoth Date: Tue, 24 May 2011 20:19:01 +0000 (+0200) Subject: A bit of a success :-) X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/ms2-kexec/commitdiff_plain/1109a23f956da8bcd71c6430020e0321d7469069?ds=sidebyside A bit of a success :-) 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 :-( --- diff --git a/Makefile b/Makefile index bc86aac..aea8202 100644 --- 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 -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: diff --git a/idmap.c b/idmap.c index e667f74..c108a73 100644 --- a/idmap.c +++ b/idmap.c @@ -1,5 +1,6 @@ #include +#include "tlbflush.h" #include #include #include @@ -88,5 +89,5 @@ void setup_mm_for_reboot(char mode) * "borrowed". */ identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE); - local_flush_tlb_all(); + my_local_flush_tlb_all(); } diff --git a/machine_kexec.c b/machine_kexec.c index e38af78..9157d4c 100644 --- a/machine_kexec.c +++ b/machine_kexec.c @@ -18,6 +18,8 @@ extern const unsigned int relocate_new_kernel_size; 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; @@ -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(®s, smp_processor_id()); - flush_cache_all(); + v7_flush_kern_cache_all(); 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; - 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*/ - flush_cache_all(); + v7_flush_kern_cache_all(); #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 - flush_cache_all(); + //v7_flush_kern_cache_all(); cpu_reset(reboot_code_buffer_phys); } diff --git a/mmu.c b/mmu.c index 7d25e16..f58a7bd 100644 --- a/mmu.c +++ b/mmu.c @@ -17,6 +17,7 @@ #include #include +#include "tlbflush.h" #include #include #include @@ -41,19 +42,7 @@ void setup_mm_for_reboot(char mode) 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; @@ -66,4 +55,5 @@ void setup_mm_for_reboot(char mode) pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); flush_pmd_entry(pmd); } + my_local_flush_tlb_all(); } diff --git a/proc-v7.S b/proc-v7.S index 402ec2b..fe7ffed 100644 --- 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) + 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 + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + ldmfd sp!, {pc} mov pc, lr ENDPROC(cpu_v7_proc_fin) diff --git a/relocate_kernel.S b/relocate_kernel.S index 9cf4cbf..f2b7868 100644 --- a/relocate_kernel.S +++ b/relocate_kernel.S @@ -6,6 +6,15 @@ .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 diff --git a/sys.c b/sys.c index 611276b..23eb124 100644 --- a/sys.c +++ b/sys.c @@ -63,8 +63,8 @@ void kernel_restart_prepare(char *cmd) blocking_notifier_call_chain(¬ifier_head, SYS_RESTART, cmd); system_state = SYSTEM_RESTART; -// device_shutdown(); -// sysdev_shutdown(); + //device_shutdown(); + //sysdev_shutdown(); } /* diff --git a/tlbflush.h b/tlbflush.h index d2005de..51de998 100644 --- a/tlbflush.h +++ b/tlbflush.h @@ -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))) -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;