关于head.S中的mmu使能

发布于 2022-09-30 05:31:44 字数 10678 浏览 7 评论 0

当内核启动后出现下列信息后就死机了
Booting image at 02030000 ...
Image Name: Linux-2.6.9-Centaur
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 855828 Bytes = 835.8 kB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
OK
No initrd
## Transferring control to Linux (at address 00008000) ...

Starting kernel ...

Uncompressing Linux........................................................ done
, booting the kernel.

于是跟踪代码到arch/arm/kernel/head.S并且使能CONFIG_DEBUG_LL宏开启low-level debug 功能.相关代码如下:

        bl        __create_page_tables

        /*
         * The following calls CPU specific code in a position independent
         * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
         * xxx_proc_info structure selected by __lookup_architecture_type
         * above.  On return, the CPU will be ready for the MMU to be
         * turned on, and r0 will hold the CPU control register value.
         */
        adr        lr, __turn_mmu_on                @ return (PIC) address
               
                STMFD SP!,{R0-R12,LR}
                mov r0,#'a'
                bl printch @输出字符a
                LDMFD SP!,{R0-R12,LR}

        add        pc, r10, #12

/*
* Enable the MMU.  This completely changes the structure of the visible
* memory space.  You will not be able to trace execution through this.
* If you have an enquiry about this, *please* check the linux-arm-kernel
* mailing list archives BEFORE sending another post to the list.
*/
        .align        5
        .type        __turn_mmu_on, %function
__turn_mmu_on:
        ldr        lr, __switch_data
               
                STMFD SP!,{R0-R12,LR}
                mov r0,#'b'
                bl printch @输出字符b
                LDMFD SP!,{R0-R12,LR}              

#ifdef CONFIG_ALIGNMENT_TRAP
        orr        r0, r0, #2                        @ ...........A.
#endif
                        mcr        p15, 0, r0, c1, c0, 0                @ write control reg
           mrc        p15, 0, r3, c0, c0, 0                @ read id reg

                STMFD SP!,{R0-R12,LR}
                mov r0,#'c'
                bl printch @输出字符c
                LDMFD SP!,{R0-R12,LR}

        mov        r3, r3
        mov        r3, r3
        mov        pc, lr
.......................

#ifdef CONFIG_DEBUG_LL
        /*
         * Map in IO space for serial debugging.
         * This allows debug messages to be output
         * via a serial console before paging_init.
         */
        add        r0, r4, r7
        rsb        r3, r7, #0x4000                        @ PTRS_PER_PGD*sizeof(long)
        cmp        r3, #0x0800
        addge        r2, r0, #0x0800
        addlt        r2, r0, r3
        orr        r3, r6, r8
1:        str        r3, [r0], #4
        add        r3, r3, #1 << 20
        teq        r0, r2
        bne        1b
       

arch/arm/kernel/debug.S:
                .macro        addruart,rx
                mrc        p15, 0, \rx, c1, c0
                tst        \rx, #1                        @ MMU enabled?
                ldreq        \rx, =KS_IO_BASE        @ physical base address
                ldrne        \rx, =KS_VIO_BASE        @ virtual base
                add        \rx, \rx, #KS_UART_RX_BUFFER
                .endm

                .macro        senduart,rd,rx
                strb        \rd, [\rx, #4]
                .endm

                .macro        waituart,rd,rx
1001:                ldr        \rd, [\rx, #0x14]        @ UART LINE STATUS
                tst        \rd, #1 << 5                @ UART RUTHRE - 0 when full
                beq        1001b
                .endm

                .macro        busyuart,rd,rx
1001:                ldr        \rd, [\rx, #0x14]        @ UART LINE STATUS
                tst        \rd, #1 << 6                @ UART URTE  - 0 when busy
                beq        1001b
                .endm

.......................
ENTRY(printascii)
                addruart r3
                b        2f
1:                waituart r2, r3
                senduart r1, r3
                busyuart r2, r3
                teq        r1, #'\n'
                moveq        r1, #'\r'
                beq        1b
2:                teq        r0, #0
                ldrneb        r1, [r0], #1
                teqne        r1, #0
                bne        1b
                mov        pc, lr

ENTRY(printch)
                addruart r3
                mov        r1, r0
                mov        r0, #0
                b        1b

这里面定义了从串口输出信息的函数printch.其中KS_IO_BASE和KS_VIO_BASE和
MACHINE_START(CENTAUR, "Micrel Centaur")
        MAINTAINER("Micrel Semiconductor Inc")
        BOOT_MEM(KS8695_MEM_START, KS_IO_BASE, KS_VIO_BASE)
        ....................
MACHINE_END
这个宏中的定义是一样的.       

从上面代码可以看出不管在mmu是否开启的情况下,都是可以通过串口输出字符的。

但运行结果就是字符a和字符b输出,但是mrc        p15, 0, r3, c0, c0, 0语句后并没有字符c输出,初步断定要么是io映射没有做好,
要么就是mmu使能的时候出错了。

请问各位真正的原因是什么?如何解决呢?
或者我可以绕过这个问题,继续调试下去呢?
多谢各位了!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文