<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM Linux啟動(dòng)分析headarmv.S內(nèi)幕

          ARM Linux啟動(dòng)分析headarmv.S內(nèi)幕

          作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
          __create_page_tables:
          pgtbl r4, r5 @ page table address

          /* Clear the 16K level 1 swapper page table */
          mov r0, r4
          mov r3, #0
          add r2, r0, #0x4000
          1: str r3, [r0], #4
          str r3, [r0], #4
          str r3, [r0], #4
          str r3, [r0], #4
          teq r0, r2
          bne 1b

          /*
          * Create identity mapping for first MB of kernel to
          * cater for the MMU enable.This identity mapping
          * will be removed by paging_init()
          */
          krnladrr2, r4, r5 @ start of kernel
          add r3, r8, r2 @ flags + kernel base
          str r3, [r4, r2, lsr #18] @ identity mapping

          /*
          * Now setup the pagetables for our kernel direct
          * mapped region.We round TEXTADDR down to the
          * nearest megabyte boundary.
          */
          add r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel
          bic r2, r3, #0x00f00000
          str r2, [r0] @ PAGE_OFFSET + 0MB
          add r0, r0, #(TEXTADDR & 0x00f00000) >> 18
          str r3, [r0], #4 @ KERNEL + 0MB
          add r3, r3, #1 << 20
          str r3, [r0], #4 @ KERNEL + 1MB
          add r3, r3, #1 << 20
          str r3, [r0], #4 @ KERNEL + 2MB
          add r3, r3, #1 << 20
          str r3, [r0], #4 @ KERNEL + 3MB

          /*
          * Ensure that the first section of RAM is present.
          * we assume that:
          *1. the RAM is aligned to a 32MB boundary
          *2. the kernel is executing in the same 32MB chunk
          * as the start of RAM.
          */
          bic r0, r0, #0x01f00000 >> 18 @ round down
          and r2, r5, #0xfe000000 @ round down
          add r3, r8, r2 @ flags + rambase
          str r3, [r0]

          bic r8, r8, #0x0c @ turn off cacheable
          @ and bufferable bits
          代碼創(chuàng)建頁表目錄。首先清空從0xA0004000開始的16K頁表項(xiàng)。然后,為了可以訪問從0xA0000000開始的內(nèi)核的1M空間,將該地址對(duì)應(yīng)的頁表項(xiàng)賦值。接著映射從TEXTADDR開始的4M的虛擬地址空間,這需要4個(gè)頁表項(xiàng)。最后,由于SDRAM開始的第一MB的空間存放有啟動(dòng)時(shí)的一些參數(shù),所以也需要映射。在這里,該映射和前面的虛擬地址的映射在地址上是相等的。

          在創(chuàng)建頁表目錄完成后,代碼通過前面主程序的最后一句addpc, r10, #12跳轉(zhuǎn)到實(shí)際的CPU的設(shè)置子程序__xscale_setup。
          __xscale_setup:
          mov r0, #F_BIT|I_BIT|SVC_MODE
          msr cpsr_c, r0
          mcr p15, 0, ip, c7, c7, 0@ invalidate I, D caches & BTB
          mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
          mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs
          mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
          mov r0, #0x1f @ Domains 0, 1 = client
          mcr p15, 0, r0, c3, c0, 0@ load domain access register
          mov r0, #1 @ Allow user space to access
          mcr p15, 0, r0, c15, c1, 0 @ ... CP 0 only.
          #if CACHE_WRITE_THROUGH
          mov r0, #0x20
          #else
          Mov r0, #0x00
          #endif
          mcr p15, 0, r0, c1, c1, 0 @ set auxiliary control reg
          mrc p15, 0, r0, c1, c0, 0 @ get control register
          bic r0, r0, #0x0200 @ ......R.........
          bic r0, r0, #0x0082 @ ........B.....A.
          orr r0, r0, #0x0005 @ .............C.M
          orr r0, r0, #0x3900 @ ..VIZ..S........
          #ifdef CONFIG_XSCALE_CACHE_ERRATA
          bic r0, r0, #0x0004 @ see cpu_xscale_proc_init
          #endif
          mov pc, lr
          主要是操作協(xié)處理器,設(shè)置頁表目錄項(xiàng)基地址,對(duì)CACHE和BUFFER的控制位進(jìn)行一些操作。具體大家可以看看介紹ARM編程的書。

          .type__switch_data, %object
          __switch_data:.long__mmap_switched
          .long SYMBOL_NAME(__bss_start)
          .long SYMBOL_NAME(_end)
          .long SYMBOL_NAME(processor_id)
          .long SYMBOL_NAME(__machine_arch_type)
          .long SYMBOL_NAME(cr_alignment)
          .long SYMBOL_NAME(init_task_union)+8192

          .type __ret, %function
          __ret: ldr lr, __switch_data
          mcr p15, 0, r0, c1, c0
          mov r0, r0
          mov r0, r0
          mov r0, r0
          mov pc, lr

          .align 5
          __mmap_switched:
          adr r3, __switch_data + 4
          ldmia r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat
          @ sp = stack pointer

          mov fp, #0 @ Clear BSS (and zero fp)
          1: cmp r4, r5
          strcc fp, [r4],#4
          bcc 1b

          str r9, [r6] @ Save processor ID
          str r1, [r7] @ Save machine type
          #ifdef CONFIG_ALIGNMENT_TRAP
          orr r0, r0, #2 @ ...........A.
          #endif
          bic r2, r0, #2 @ Clear A bit
          stmia r8, {r0, r2} @ Save control register values
          bSYMBOL_NAME(start_kernel)
          最后這段代碼的作用主要是在進(jìn)入C函數(shù)前先做一些變量的初始化和保存工作。首先清空BSS區(qū)域,然后保存處理器ID和機(jī)器類型到各自變量地址,接著保存cr_alignment,最后跳轉(zhuǎn)到init/main.c中的start_kernel函數(shù)運(yùn)行。

          以上介紹的是head-armv.S文件的主要內(nèi)容和功能,它是linux運(yùn)行的第一個(gè)文件,具有非常重要的意義。很好的閱讀該文件,對(duì)于我們理解ARM處理器的工作方式有很大的幫助。同時(shí),在許多l(xiāng)inux系統(tǒng)的移植工作中,往往需要對(duì)該文件透徹的理解。


          關(guān)鍵詞: ARMLinux啟動(dòng)分

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();