This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Dual core boot up issue (Enabling MMU causes Linux hang)

Note: This was originally posted on 23rd June 2009 at http://forums.arm.com

Hello,

I adopt IOP81342 (Intel XScale processor, adopt ARM v5TE architecture) to a H/W board, and plan to running Linux (2.6.11.12) 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 (2.6.11.12) 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
5. /arch/arm/kernel/head.S
    - 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) for 3 weeks long, 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,
Milton Wang
  • Note: This was originally posted on 23rd June 2009 at http://forums.arm.com

    I have tried some methods to set  I/D cache & BTB is invalidated before enable MMU, but core1 still hang when mmu  on

    experiment 1.
    mcr p15, 0, r0, c7, c7, 0  @ invalidate I/D cache & BTB
    mcr p15, 0, r0, c8, c7, 0  @ globally invalidate I,D TLB

    experiment 2.
    mcr p15, 0, r11, c7, c7, 0  @ invalidate I, D caches & BTB
    mcr p15, 0, r11, c7, c10, 4 @ Drain Write Buffer
    mcr p15, 0, r11, c7, c10, 5 @ Data memory barrier
    mcr p15, 0, r11, c7, c5, 4  @ Prefetch Flush
  • Note: This was originally posted on 24th June 2009 at http://forums.arm.com

    I am not expert in linux but I have observed this behavior when MMU is enaled without properly creating page table.
    once you enable MMU , it will start using page table to map virtual to physical address and if something is wrong it hanges.


    Thank you for your advise.
    I have traced code and results, but I can not find abnormal from page table and translation table base address

    r4=0x08004018  (translation table base address)
    r5=0x0000003D  (domain access permissions)
    PC=0x080081D4 (before enable mmu, the program counter is at 128MB physical address)

    Page table:
    08004000: 00000C0E 00100C0E 00200C0E 00300C0E  00400C0E 00500C0E 00600C0E 00700C0E
    08004020: 00800C0E 00900C0E 00A00C0E 00B00C0E  00C00C0E 00D00C0E 00E00C0E 00F00C0E
    08004040: 01000C0E 01100C0E 01200C0E 01300C0E  01400C0E 01500C0E 01600C0E 01700C0E
    08004060: 01800C0E 01900C0E 01A00C0E 01B00C0E  01C00C0E 01D00C0E 01E00C0E 01F00C0E
    08004080: 02000C0E 02100C0E 02200C0E 02300C0E  02400C0E 02500C0E 02600C0E 02700C0E
    080040A0: 02800C0E 02900C0E 02A00C0E 02B00C0E  02C00C0E 02D00C0E 02E00C0E 02F00C0E
    080040C0: 03000C0E 03100C0E 03200C0E 03300C0E  03400C0E 03500C0E 03600C0E 03700C0E
    080040E0: 03800C0E 03900C0E 03A00C0E 03B00C0E  03C00C0E 03D00C0E 03E00C0E 03F00C0E
    08004100: 04000C0E 04100C0E 04200C0E 04300C0E  04400C0E 04500C0E 04600C0E 04700C0E
    08004120: 04800C0E 04900C0E 04A00C0E 04B00C0E  04C00C0E 04D00C0E 04E00C0E 04F00C0E
    08004140: 05000C0E 05100C0E 05200C0E 05300C0E  05400C0E 05500C0E 05600C0E 05700C0E
    08004160: 05800C0E 05900C0E 05A00C0E 05B00C0E  05C00C0E 05D00C0E 05E00C0E 05F00C0E
    08004180: 06000C0E 06100C0E 06200C0E 06300C0E  06400C0E 06500C0E 06600C0E 06700C0E
    080041A0: 06800C0E 06900C0E 06A00C0E 06B00C0E  06C00C0E 06D00C0E 06E00C0E 06F00C0E
    080041C0: 07000C0E 07100C0E 07200C0E 07300C0E  07400C0E 07500C0E 07600C0E 07700C0E
    080041E0: 07800C0E 07900C0E 07A00C0E 07B00C0E  07C00C0E 07D00C0E 07E00C0E 07F00C0E
    08004200: 08000C0E 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    08004220: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    08004240: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    ....
    08004FE0: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    08005000: 08000C0E 08100C0E 08200C0E 08300C0E  08400C0E 00000000 00000000 00000000
    08005020: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    08005040: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    08005060: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    08005080: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    080050A0: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    080050C0: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    080050E0: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000
    08005100: 00000000 00000000 00000000 00000000  00000000 00000000 00000000 00000000

    a). the page table is begin from 0x08004000 (128MB+16KB)
    :). mapped first 128MB (0 ~ 128MB, PA:VA is 1:1)
    c). mapped below continuous 6MB space for kernel code
    0x40000000 (VA) ->  0x08000000 (PA)
    0x40000000 (VA) ->  0x08000000 (PA)
    0x40100000 (VA) ->  0x08100000 (PA)
    0x40200000 (VA) ->  0x08200000 (PA)
    0x40300000 (VA) ->  0x08300000 (PA)
    0x40300000 (VA) ->  0x08400000 (PA)


    Please help check it and give your suggestion for further experiments, thank you very much.
  • Note: This was originally posted on 23rd June 2009 at http://forums.arm.com

    I am not expert in linux but I have observed this behavior when MMU is enaled without properly creating page table.
    once you enable MMU , it will start using page table to map virtual to physical address and if something is wrong it hanges.