I adopt IOP81342 (Intel XScale processor, adopt ARM v5TE architecture) to a H/W board, and plan to running Linux (126.96.36.199) on both cores for improve functions and performance. I installed 1GB DDR2 memory to H/W board and allocated first 128MB (address space 0 ~ 127MB) for core0, remain capacity 896MB (address space 128MB ~ 1024MB) is reserve for core1.
I modify Redboot bootloader and Linux source code (188.8.131.52) to init core1 and let it execute Linux at 128MB address (execute kernel at 0x48008000). After tried, the core1 execution stops while enabling MMU on __turn_mmu_on function (/arch/arm/kernel/head.S).
List IOP342 core1 execution sequence as below:
1. Power on, Bootloader execute and success all scheduled jobs
- initial CPU/I2C/DRAM controller/UART port
- DRAM test
- check FLASH and move compressed zimage to memory 0x0804b810 (original is 0x4b810)
- setup ATAG structure and move them to address 0x08000100 (original is 0x100)
- jump the execution address to entry address of zimage (compressed kernel on address 0x0804b810)
2. After execute misc.c and head.S , core1 uncompressed zImage to vmlinux to address of 0x48008000 (original is 0x40008000), and then jump the execution address to kernel startup entry (stext function, /arch/arm/kernel/head.S) to starting Linux.
3. During kernel startup, core1 execute and success some functions likes __lookup_processor_type,
__lookup_machine_type, __create_page_tables, __xsc3_setup, __enable_mmu ....
4. Core1 hanged at __turn_mmu_on function. After troubleshooting via debug message (display on UART) and on board LEDs, I observed core1 hang result when write control register to CP15 to enable MMU (instruction mcr p15, 0, r0, c1, c0, 0).
After resume bootloader and kernel code to original setting, the IOP342 core1 can execute Linux on virtual address 0x40008000 (physical address 0x8000). Therefore, I suspect the problem may cause by software setting (wrong setting, or lost some steps before __turn_mmu_on function),
List my modification of kernel codes as below, please check it and provide your suggestion to me, thank you very much.
1. Add 128MB offset on Makefile.boot (/arch/arm/mach-iop13xx/Makefile.boot)
zreladdr-y := 0x08008000
params_phys-y := 0x08000100
initrd_phys-y := 0x08800000
2. Re-define PHYS_OFFSET (/include/asm-arm/arch-iop13xx/memory.h)
#define PHYS_OFFSET UL(0x08000000) /* add128MB offset */
3. Re-define BOOT_PARAM_OFFSET (/include/asm-arm/arch/iq81340.h)
#define BOOT_PARAM_OFFSET 0x08000100 /* add128MB offset */
This variable is declare for BOOT_MEM(PHYS_RAM, PHYS_IO, IO_PG_OFFSET) (/arch/arm/mach-iop13xx/iop1340-setup.c)
4. Enable coprocessor access CP13,CP7,CP6 and CP0 on __xsc3_setup function (\arch\arm\mm\proc-xsc3.S)
ldr r0, =0x20c1 @ enable coprocessor access CP13,CP7,CP6,CP0
mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes
- Provide functions to debugging system hang issue (via UART port or debug LEDs)
The purpose of this project is running Linux on dual cores for RAID application, and the first task is change Linux kernel start address and startup it at specific address (0x8008000 in this case)
This is my first experience in Linux kernel development. I trying solve this problem by any methods (experiments, read textbook, linux documents, and searching technical doc/support from INTERNET), but I don't have idea how to fix this.
How to change the Linux Kernel Start Address? Could anyone give me a detail example for booting Linux on specific address?
Or help check my problem and give your suggestion for further debugging?
Any help in this regard will be greatly appreciated.
Thank you very much,