国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

linux內核啟動解析(二)

發布時間:2012-4-1 09:55    發布者:李寬
關鍵詞: linux
freshtree

1.1 __lookup_processor_type()

話說內核映像解壓后,又跳到c0008000這個地址。這個地址指向內核代碼的什么地方,我們肯定很想知道。在arch/arm/kernel/vmlinux.lds.S中,可以發現這樣的代碼:

SECTIONS

{

#ifdef CONFIG_XIP_KERNEL

       . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);

#else

       . = PAGE_OFFSET + TEXT_OFFSET;

#endif

       .text.head : {

              _stext = .;

              _sinittext = .;

              *(.text.head)

       }



}

一般內核都不配置成XIP方式的,所以這段腳本等同于:

SECTIONS

{

       . = PAGE_OFFSET + TEXT_OFFSET;

       .text.head : {

              _stext = .;

              _sinittext = .;

              *(.text.head)

       }



}

這段腳本告訴我們SECTIONS的起始地址是 .text.head的起始地址_stext,且

_stext= PAGE_OFFSET + TEXT_OFFSET;

PAGE_OFSET在.config文件中設置:

PAGE_OFFSET=0xC0000000;

TEXT_OFFSET在主目錄下的Makefile文件中設置:

textofs-y   := 0x00008000

TEXT_OFFSET := $(textofs-y)



結合arch/arm/kernel/head.S,會發現如下代碼:

.section ".text.head", "ax"

ENTRY(stext)

       msr  cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode

                                          @ and irqs disabled

       mrc p15, 0, r9, c0, c0          @ get processor id

       bl     __lookup_processor_type             @ r5=procinfo r9=cupid



ENDPROC(stext)

第一句代碼的意思是表示下面的內容都屬于.text.head 段的,”ax”表示這段內容是可分配且可執行的(allocable and executable) 。

所以c0008000處放的代碼就是stext的入口地址。接下來的

msr  cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE

就是把fiq_mask(快速中斷屏蔽位)和irq_mask(快速中斷屏蔽位)都置位,同時把處理器模式設置為svc模式。這就是要告訴閑雜人等不要來打擾,這里要辦重要的事。cpsr_c 代表當前狀態寄存器;鑒于當前狀態寄存器的重要性,arm特意開發了msr指令,專門用來設置當前狀態寄存器。

mrc p15, 0, r9, c0, c0

是將協處理器cp15 c0的值賦值到r9中。接下來的

bl     __lookup_processor_type

是長跳轉到__lookup_processor_type,查看processor ID是否被內核支持。

__lookup_processor_type:

       adr   r3, 3f

       ldmda      r3, {r5 - r7}

       sub  r3, r3, r7               @ get offset between virt&phys

       add  r5, r5, r3               @ convert virt addresses to

       add  r6, r6, r3               @ physical address space

1:     ldmia       r5, {r3, r4}                   @ value, mask

       and  r4, r4, r9               @ mask wanted bits

       teq   r3, r4

       beq  2f

       add  r5, r5, #PROC_INFO_SZ             @ sizeof(proc_info_list)

       cmp r5, r6

       blo   1b

       mov r5, #0                           @ unknown processor

2:     mov pc, lr

ENDPROC(__lookup_processor_type)

adr是條偽指令,作用就是把標號為3位置的地址賦值給r3寄存器。3后面加f是表示這是個長距離(far)的標號。有同學可能就要問了,ldr也能起到這個作用,為什么不用ldr?首先 ldr r3, 3f取的是標號3這個地址的內容,而不是地址本身;其次,可以用ldr r3,=3f來取地址本身,但這是一個絕對地址;而adr取得的是相對地址。如果要保證程序在任何內存都能運行,就必須保證代碼是地址無關的,也就是PIC(position independent code)。顯然adr偽指令很對PIC的胃口,它的取相對地址方式符合PIC的設定。

       .long       __proc_info_begin

       .long       __proc_info_end

3:     .long       .

       .long       __arch_info_begin

       .long       __arch_info_end

我們接著往下看。

ldmda      r3, {r5 - r7}

       sub  r3, r3, r7               @ get offset between virt&phys

       add  r5, r5, r3               @ convert virt addresses to

       add  r6, r6, r3               @ physical address space

1:     ldmia       r5, {r3, r4}                   @ value, mask

       and  r4, r4, r9               @ mask wanted bits

       teq   r3, r4

       beq  2f

       add  r5, r5, #PROC_INFO_SZ             @ sizeof(proc_info_list)

       cmp r5, r6

       blo   1b

       mov r5, #0                           @ unknown processor

2:     mov pc, lr

ldmada r3,(r5-r7) 是把標簽3所指的地址的內容(也就是標簽3的虛擬地址)賦值給r7,把比標簽3所指的地址小4的地址的內容(也就是__proc_info_end)賦值給r6,把比標簽3所指的地址小8的地址的內容(__proc_info_begin)賦值給r5。這里的虛擬地址是線性邏輯地址,它和物理地址之間有著一一映射關系。因為__proc_info_begin 和__proc_info_end都是虛擬地址,此時我們MMU還沒有打開,就必須要使用物理地址。這就需要我們先把它們轉換為物理地址。接下來的三句代碼就是完成這樣的工作。

__proc_info_begin和__proc_info_end是在vlinux.lds.S中定義的。

__proc_info_begin = .;

                     *(.proc.info.init)

              __proc_info_end = .;

這說明在__proc_info_begin和__proc_info_end之間的是所有的.proc.info.init段。我們可以在arch/arm/mm/proc_*.S中找到相應的.proc.info.init段。Smdk6410屬于armv6,我們可以在proc_v6.S找到armv6處理器的id和id掩碼。

之后的代碼就是把處理器的id和id掩碼賦值到r3,r4中;把r9與處理器掩碼做與操作,然后與處理器id(r3)比較,看是否相等;如不相等,就取下一個處理器id進行比較;如果到最后都沒有處理器id相符,就將r5賦值為0:

1:     ldmia       r5, {r3, r4}                   @ value, mask

       and  r4, r4, r9               @ mask wanted bits

       teq   r3, r4

       beq  2f

       add  r5, r5, #PROC_INFO_SZ             @ sizeof(proc_info_list)

       cmp r5, r6

       blo   1b

       mov r5, #0                           @ unknown processor

2:     mov pc, lr

最后一句是跳出__lookup_processor_type函數。跳出之后會對處理器id是否有效做一個判斷;如果不是有效的處理器,就進行相應的錯誤處理;如果是有效的處理器,就進行機器類型查找:

       movs      r10, r5                         @ invalid processor (r5=0)?

       beq  __error_p                     @ yes, error 'p'

bl     __lookup_machine_type        @ r5=machinfo
本文地址:http://m.qingdxww.cn/thread-88591-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • Cortex-M4外設 —— TC&TCC結合事件系統&DMA優化任務培訓教程
  • 更佳設計的解決方案——Microchip模擬開發生態系統
  • 我們是Microchip
  • 想要避免發生災難,就用MPLAB SiC電源仿真器!
  • 貿澤電子(Mouser)專區

相關視頻

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99久久精品免费观看国产 | 亚洲综合色在线观看 | 久久香蕉热 | 极品美女一区二区三区视频 | 日本黄色网址免费 | 1000部羞羞视频在线看视频 | 好吊色欧美一区二区三区四区 | 一区二区视频在线播放 | 第一福利视频 | 久99久热只有精品国产99 | 日韩中文字幕高清在线专区 | 黄色片网站免费在线观看 | 国产自在线 | 欧美日韩不卡视频一区二区三区 | 欧美成人免费在线 | 伊人五月婷婷 | 欧美a图| 国产人成午夜免视频网站 | 欧美日韩精品免费一区二区三区 | 欧美精品 在线观看 | 麻豆天美果冻星空91制片厂 | 99视频精品国在线视频艾草 | 一区二区三区高清视频在线观看 | 国产xxwwxxww视频 | 亚洲国产精品激情在线观看 | 日韩福利在线 | 日韩精品国产自在欧美 | 失乐园电视剧日本第6集 | 欧美成人h版影院在线播放 欧美成人h版影片在线观看 | 曰韩在线 | 精品欧美一区二区三区免费观看 | 91在线公开视频 | 花季传媒v3.024 | 久久久久久国产精品mv | 榴莲视频app下载安装 | 尹人视频在线观看 | 中文字幕导航 | 毛片一级黄色 | 亚洲黄色一级 | 欧美另类视频一区二区三区 | 女人18毛片一级毛片在线 |