offst 的作用及使用方法(2)

行7和行8定义了这两个变量,phys_io:物理IO的起始地址,io_pg_offst:IO页表的偏移字节的地址(MMU页表)。phys_io 用来保存 UART 的物理地址,io_pg_offst 用来保存 UART 的内核空间虚拟地址。两者的映射关系在 arch/arm/kernel/head.S 中建立。这样,在 kernel 没有初始化完 MMU 时,就可以通过写 io_pg_offst 向 UART 打印调试信息。这主要在 low level 的调试函数中使用,比如 printascii。

2. phys_io 与 io_pg_offst 的映射关系如何建立

现在可以进入arch\arm\kernel\head.S中分析这两个变量的具体调用情况:

[cpp]

/*   *  linux/arch/arm/kernel/head.S   *   *  Copyright (C) 1994-2002 Russell King   *  Copyright (c) 2003 ARM Limited   *  All Rights Reserved   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2 as   * published by the Free Software Foundation.   *   *  Kernel startup code for all 32-bit CPUs   */   ............   ............   ............   /*   * Kernel startup entry point.   * ---------------------------   *   * This is normally called from the decompressor code.  The requirements   * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,   * r1 = machine nr, r2 = atags pointer.   *   * This code is mostly position independent, so if you link the kernel at   * 0xc0008000, you call this at __pa(0xc0008000).   *   * See linux/arch/arm/tools/mach-types for the complete list of machine   * numbers for r1.   *   * We're trying to keep crap to a minimum; DO NOT add any machine specific   * crap here - that's what the boot loader (or in extreme, well justified   * circumstances, zImage) is for.   */       __HEAD   ENTRY(stext)       setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode                           @ and irqs disabled       mrc p15, 0, r9, c0, c0      @ get processor id       bl  __lookup_processor_type     @ r5=procinfo r9=cpuid       movs    r10, r5             @ invalid processor (r5=0)?       beq __error_p           @ yes, error 'p'       bl  __lookup_machine_type       @ r5=machinfo       movs    r8, r5              @ invalid machine (r5=0)?       beq __error_a           @ yes, error 'a'       bl  __vet_atags       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_machine_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.       */       ldr r13, __switch_data      @ address to jump to after                           @ mmu has been enabled       adr lr, BSYM(__enable_mmu)      @ return (PIC) address    ARM(   add pc, r10, #PROCINFO_INITFUNC )    THUMB( add r12, r10, #PROCINFO_INITFUNC    )    THUMB( mov pc, r12             )   ENDPROC(stext)   .....   .....   .....   /*   * Setup the initial page tables.  We only setup the barest   * amount which are required to get the kernel running, which   * generally means mapping in the kernel code.   *   * r8  = machinfo   * r9  = cpuid   * r10 = procinfo   *   * Returns:   *  r0, r3, r6, r7 corrupted   *  r4 = physical page table address   */   __create_page_tables:       pgtbl   r4              @ page table address          /*       * Clear the 16K level 1 swapper page table       */       mov r0, r4       mov r3, #0       add r6, r0, #0x4000   1:  str r3, [r0], #4       str r3, [r0], #4       str r3, [r0], #4       str r3, [r0], #4       teq r0, r6       bne 1b          ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags          /*       * Create identity mapping for first MB of kernel to       * cater for the MMU enable.  This identity mapping       * will be removed by paging_init().  We use our current program       * counter to determine corresponding section base address.       */       mov r6, pc       mov r6, r6, lsr #20         @ start of kernel section       orr r3, r7, r6, lsl #20     @ flags + kernel base       str r3, [r4, r6, lsl #2]        @ identity mapping          /*       * Now setup the pagetables for our kernel direct       * mapped region.       */       add r0, r4,  #(KERNEL_START & 0xff000000) >> 18       str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!       ldr r6, =(KERNEL_END - 1)       add r0, r0, #4       add r6, r4, r6, lsr #18   1:  cmp r0, r6       add r3, r3, #1 << 20       strls   r3, [r0], #4       bls 1b      #ifdef CONFIG_XIP_KERNEL        /*       * Map some ram to cover our .data and .bss areas.       */       orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)       .if (KERNEL_RAM_PADDR & 0x00f00000)       orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)       .endif       add r0, r4,  #(KERNEL_RAM_VADDR & 0xff000000) >> 18       str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!       ldr r6, =(_end - 1)       add r0, r0, #4       add r6, r4, r6, lsr #18   1:  cmp r0, r6       add r3, r3, #1 << 20       strls   r3, [r0], #4       bls 1b   #endif           /*       * Then map first 1MB of ram in case it contains our boot params.       */       add r0, r4, #PAGE_OFFSET >> 18       orr r6, r7, #(PHYS_OFFSET & 0xff000000)       .if (PHYS_OFFSET & 0x00f00000)       orr r6, r6, #(PHYS_OFFSET & 0x00f00000)       .endif       str r6, [r0]      #ifdef CONFIG_DEBUG_LL        ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags       /*       * Map in IO space for serial debugging.       * This allows debug messages to be output       * via a serial console before paging_init.       */       ldr r3, [r8, #MACHINFO_PGOFFIO]       add r0, r4, r3       rsb r3, r3, #0x4000         @ PTRS_PER_PGD*sizeof(long)       cmp r3, #0x0800         @ limit to 512MB       movhi   r3, #0x0800       add r6, r0, r3       ldr r3, [r8, #MACHINFO_PHYSIO]       orr r3, r3, r7   1:  str r3, [r0], #4       add r3, r3, #1 << 20       teq r0, r6       bne 1b   #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)        /*       * If we're using the NetWinder or CATS, we also need to map       * in the 16550-type serial port for the debug messages       */       add r0, r4, #0xff000000 >> 18       orr r3, r7, #0x7c000000       str r3, [r0]   #endif    #ifdef CONFIG_ARCH_RPC        /*       * Map in screen at 0x02000000 & SCREEN2_BASE       * Similar reasons here - for debug.  This is       * only for Acorn RiscPC architectures.       */       add r0, r4, #0x02000000 >> 18       orr r3, r7, #0x02000000       str r3, [r0]       add r0, r4, #0xd8000000 >> 18       str r3, [r0]   #endif    #endif        mov pc, lr   ENDPROC(__create_page_tables)  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyzjfs.html