亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現在的位置是:首頁 > 技術閱讀 >  u-boot2020.04移植(2、從鏈接腳本開始)

u-boot2020.04移植(2、從鏈接腳本開始)

時間:2024-05-31

點擊下方閱讀原文可訪問文中超鏈接

首先分析一下u-boot的鏈接腳本,這樣就能夠知道u-boot本身的大體組成及分布,如果想更詳細的了解,可以查看生成的u-boot.map文件,這個文件就能看出u-boot各個段的排布。在上一篇文章中,已經完成了u-boot的編譯,在u-boot根目錄下可以看到生成了一個u-boot.lds文件,這個文件就是u-boot的鏈接腳本,它是由arch\arm\cpu\u-boot.lds文件經過處理后得到的,其內容如下:

OUTPUT_FORMAT("elf32-littlearm""elf32-littlearm""elf32-littlearm")
OUTPUT_ARCH(arm)
/*整個u-boot的入口*/
ENTRY(_start)
SECTIONS
{
 . = 0x00000000;
 . = ALIGN(4);
 .text :
 {
   /*這個和以前舊的u-boot版本不一樣,這個現在被定義在arch/arm/lib/sections.c文件中,
   對應頭文件為include/asm-generic/sections.h,
   用的是零長數組來實現,不占內存空間,相當于只是放了一個符號,u-boot重定位時就是從這個地址開始拷貝*/

  *(.__image_copy_start)
  /*存放向量表的段,位于arch/arm/lib/vectors.S文件*/
  *(.vectors)
  /*這個就相當于是u-boot代碼執行的開始了(但第一句執行的代碼不在這兒)*/
  arch/arm/cpu/armv7/start.o (.text*)
 }
 /*表示efi_runtime段的開始*/
 .__efi_runtime_start : {
  *(.__efi_runtime_start)
 }
 .efi_runtime : {
  *(.text.efi_runtime*)
  *(.rodata.efi_runtime*)
  *(.data.efi_runtime*)
 }
 /*表示efi_runtime段的結束*/
 .__efi_runtime_stop : {
  *(.__efi_runtime_stop)
 }
 .text_rest :
 {
   /*u-boot代碼段*/
  *(.text*)
 }
 . = ALIGN(4);
   /*u-boot只讀數據段*/
 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
 . = ALIGN(4);
 .data : {
   /*u-boot數據段*/
  *(.data*)
 }
 . = ALIGN(4);
 . = .;
 . = ALIGN(4);
 .u_boot_list : {
   /*u-boot自定義段,u-boot命令、硬件驅動、環境變量相關的一些東西等放在此段(*號是通配符),具體的段可以查看u-boot.map文件*/
  KEEP(*(SORT(.u_boot_list*)));
 }
 . = ALIGN(4);
 .efi_runtime_rel_start :
 {
  *(.__efi_runtime_rel_start)
 }
 .efi_runtime_rel : {
  *(.rel*.efi_runtime)
  *(.rel*.efi_runtime.*)
 }
 .efi_runtime_rel_stop :
 {
  *(.__efi_runtime_rel_stop)
 }
 . = ALIGN(4);
 .image_copy_end :
 {
   /*u-boot重定位拷貝結束的地址*/
  *(.__image_copy_end)
 }
 .rel_dyn_start :
 {
   /*動態符號表的開始*/
  *(.__rel_dyn_start)
 }
 .rel.dyn : {
   /*放置了動態符號表,也是重定位的時候需要的*/
  *(.rel*)
 }
 .rel_dyn_end :
 {
   /*動態符號表的結束*/
  *(.__rel_dyn_end)
 }
 .end :
 {
  *(.__end)
 }
 /*整個u-boot bin文件的結束*/
 _image_binary_end = .;
 . = ALIGN(4096);
 .mmutable : {
   /*MMU頁表相關*/
  *(.mmutable)
 }
 /*bss段,建立C語言運行環境的時候需要*/
 .bss_start __rel_dyn_start (OVERLAY) : {
  KEEP(*(.__bss_start));
  __bss_base = .;
 }
 .bss __bss_base (OVERLAY) : {
  *(.bss*)
   . = ALIGN(4);
   __bss_limit = .;
 }
 .bss_end __bss_limit (OVERLAY) : {
  KEEP(*(.__bss_end));
 }
 /*后面是一些其它的段*/
 .dynsym _image_binary_end : { *(.dynsym) }
 .dynbss : { *(.dynbss) }
 .dynstr : { *(.dynstr*) }
 .dynamic : { *(.dynamic*) }
 .plt : { *(.plt*) }
 .interp : { *(.interp*) }
 .gnu.hash : { *(.gnu.hash) }
 .gnu : { *(.gnu*) }
 .ARM.exidx : { *(.ARM.exidx*) }
 .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}

從其內容可以得知整個u-boot程序的入口為_start這個標號,在以前的u-boot中,入口都是在start.S文件中,后面新增了一個vectors.S文件,現在_start標號就位于此文件中,所以先從此文件開始分析。

arch/arm/lib/vectors.S

/*向量表的定義*/
.macro ARM_VECTORS
/*未定義*/
#ifdef CONFIG_ARCH_K3
    ldr     pc, _reset
#else
/*從這兒可以看到,芯片上電后立馬就會執行復位*/
    b   reset
#endif
/*這里只是相當于只是一個函數指針,真正的實現在本文件的后面*/
    ldr pc, _undefined_instruction
    ldr pc, _software_interrupt
    ldr pc, _prefetch_abort
    ldr pc, _data_abort
    ldr pc, _not_used
    ldr pc, _irq
    ldr pc, _fiq
    .endm


/*從這兒可以看出,向量表被放到了專門的.vectors段中*/
    .section ".vectors""ax"

/*未定義,這是給有些芯片用來在u-boot頭部定義一些數據使用的*/
#if defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
/*
 省略注釋
 */

#include <asm/arch/boot0.h>
#else

/*
 省略注釋
 */


/*這就是整個u-boot的入口*/
_start:
/*未定義*/
#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
    .word   CONFIG_SYS_DV_NOR_BOOT_CFG
#endif
/*放置的向量表,定義在此文件的上面,和C語言的宏定義一樣*/
    ARM_VECTORS
#endif /* !defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) */

下面的內容相當于給異常處理的函數指針綁定一個函數實現的實體:

/*未定義*/
#ifdef CONFIG_ARCH_K3
_reset:            .word reset
#endif
/*這里定義了異常產生后,該去哪兒執行異常處理的過程*/
_undefined_instruction:    .word undefined_instruction
_software_interrupt:    .word software_interrupt
_prefetch_abort:    .word prefetch_abort
_data_abort:        .word data_abort
_not_used:        .word not_used
_irq:            .word irq
_fiq:            .word fiq

以undefined_instruction為例,產生異常后,先執行ldr    pc, _undefined_instruction,它會將undefined_instruction這個過程(函數)地址加載到pc指針中,這樣就相當于調用undefined_instruction這個函數了:

/*32字節對齊,2的5次方*/
    .align  5
undefined_instruction:
/*下面這些過程都是在本文件實現的,就不詳細介紹了*/
    get_bad_stack
    bad_save_user_regs
    bl  do_undefined_instruction

向量表分析了,接著執行了b reset后,下面就進入arch/arm/cpu/armv7/start.S文件了:

reset:
    /* Allow the board to save important registers */
    /*什么也沒做*/
    b   save_boot_params
save_boot_params_ret:
/*未定義*/
#ifdef CONFIG_ARMV7_LPAE
/*
 * check for Hypervisor support
 */

    mrc p15, 0, r0, c0, c1, 1       @ read ID_PFR1
    and r0, r0, #CPUID_ARM_VIRT_MASK    @ mask virtualization bits
    cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT)
    beq switch_to_hypervisor
switch_to_hypervisor_ret:
#endif

要看懂后面的內容,先得了解armv7架構的一些內容,需要參考arm的相關手冊(ARMv7-A -R Architecture Reference Manual.pdf),先看一下cpsr寄存器各個位的定義:

在這里插入圖片描述
圖1
其中與模式相關的位是bit[4:0],詳細的定義參見下圖,可以看到armv7總共有九種模式:


在這里插入圖片描述
圖2
再來看一下關于中斷和異常相關的位描述:


在這里插入圖片描述
圖3
現在繼續看后面的程序就輕松很多了,下面這段內容就是關閉中斷,并且設置CPU進入SVC32模式,關于其過程這里就不推導了,對照上面的圖,很簡單就能夠推導出來:


/*
     * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
     * except if in HYP mode already
     */

    mrs r0, cpsr
    and r1, r0, #0x1f       @ mask mode bits
    /*看是否處于HYP模式*/
    teq r1, #0x1a       @ test for HYP mode
    /*如果未在HYP模式就設置為SVC模式*/
    bicne   r0, r0, #0x1f       @ clear all mode bits
    orrne   r0, r0, #0x13       @ set SVC mode
    orr r0, r0, #0xc0       @ disable FIQ and IRQ
    msr cpsr,r0

繼續往后看,是協處理器相關的內容,還是一樣,先從手冊找到其相關的描述,建議先了解一下關于協處理器指令的使用方法,再理解這段代碼就會輕松很多:

在這里插入圖片描述
圖4 關于SCTLR寄存器的位定義


在這里插入圖片描述
圖5 關于V位的描述
下面看代碼:


#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
    /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
    mrc p15, 0, r0, c1, c0, 0   @ Read CP15 SCTLR Register
    bic r0, #CR_V       @ V = 0
    mcr p15, 0, r0, c1, c0, 0   @ Write CP15 SCTLR Register

#ifdef CONFIG_HAS_VBAR
    /* Set vector address in CP15 VBAR register */
    ldr r0, =_start
    mcr p15, 0, r0, c12, c0, 0  @Set VBAR
#endif
#endif

從cp15協處理器SCTLR寄存器V位的描述來看,設置為0的話,向量表基地址就是0x00000000,并且向量表基地址是可以被重映射的,而設置為1的話,向量表基地址就是0xffff0000,不能被重映射,因為后面u-boot會被拷貝到DRAM中運行,如果向量表還在內部IRAM的話,如果我們想使用中斷,那就訪問不到了,所以得將向量表基地址重映射,這樣產生中斷后才能正確的被響應,因此這里將V位設置為0允許重映射,然后將向量表基地址設置為_start這個標號所在的地址,從前面的內容我們知道,_start標號開始的地方就是放置的中斷向量表。

接下來cpu_init_cp15函數又是對協處理器的一堆操作,就不詳細講了,想繼續深入分析的可以參考ARMv7-A -R Architecture Reference Manual.pdf文檔,直接點擊鏈接就可下載,下面簡要的注釋一下相關的內容:

ENTRY(cpu_init_cp15)
    /*
     * Invalidate L1 I/D
     */

    mov r0, #0          @ set up for MCR
    /*TLB無效*/
    mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs
    /*指令緩存無效*/
    mcr p15, 0, r0, c7, c5, 0   @ invalidate icache
    /*分支預測無效*/
    mcr p15, 0, r0, c7, c5, 6   @ invalidate BP array
    /*數據和指令同步屏障*/
    mcr     p15, 0, r0, c7, c10, 4  @ DSB
    mcr     p15, 0, r0, c7, c5, 4   @ ISB

    /*
     * disable MMU stuff and caches
     */

    mrc p15, 0, r0, c1, c0, 0
    /*設置向量表基地址,前面已經設置過*/
    bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
    /*數據和緩存一致性失能,對齊錯誤檢查失能,MMU失能*/
    bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
    /*對齊錯誤檢查使能*/
    orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
    /*程序流預測使能*/
    orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
    /*未定義*/
#if CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
    bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
#else
    /*指令緩存使能*/
    orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
#endif
    mcr p15, 0, r0, c1, c0, 0

/*勘誤相關的都沒有定義*/
/*
省略勘誤相關的內容
*/


    mov r5, lr          @ Store my Caller
    /*讀取芯片的一些信息,如版本號、架構等,但實際上沒用到*/
    mrc p15, 0, r1, c0, c0, 0   @ r1 has Read Main ID Register (MIDR)
    mov r3, r1, lsr #20     @ get variant field
    and r3, r3, #0xf        @ r3 has CPU variant
    and r4, r1, #0xf        @ r4 has CPU revision
    mov r2, r3, lsl #4      @ shift variant field for combined value
    orr r2, r4, r2      @ r2 has combined CPU variant + revision
/* Early stack for ERRATA that needs into call C code */
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
    ldr r0, 
=(CONFIG_SPL_STACK)
#else
    /*設置一個臨時的棧用于下面的勘誤相關內容的執行,這個地址三星設置在了DRAM里面,
    要是現在我們還沒有初始化DRAM,那執行C函數的時候,程序肯定就跑飛了,好在這部分內容都沒有執行*/

    ldr r0, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
    bic r0, r0, #7  /* 8-byte alignment for ABI compliance */
    mov sp, r0

/*
省略勘誤相關的內容
*/


    /*這里就返回了*/
    mov pc, r5          @ back to my caller
ENDPROC(cpu_init_cp15)

到了這里,關于arm內核相關的東西就結束了,后面就是SOC相關的內容了。

歡迎掃碼關注我的微信公眾號

漫長當下


亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品a级| 亚洲综合色网站| 国产精品久久二区| 国产精品每日更新| 国产亚洲人成a一在线v站| 伊人激情综合| 99亚洲一区二区| 亚洲欧美卡通另类91av | 在线精品在线| 亚洲丝袜av一区| 久久精品视频在线播放| 欧美国产日产韩国视频| 国产麻豆日韩欧美久久| 亚洲精品看片| 久久久噜噜噜久久狠狠50岁| 欧美女人交a| 经典三级久久| 亚洲欧美日韩精品综合在线观看| 久久久久久网| 国产精品剧情在线亚洲| 在线国产日韩| 欧美一区二粉嫩精品国产一线天| 欧美日韩国产精品专区| 激情综合色丁香一区二区| 亚洲色图自拍| 欧美理论在线播放| **欧美日韩vr在线| 欧美一区永久视频免费观看| 欧美日韩精品综合| 亚洲精品美女在线观看播放| 免费亚洲视频| 国产欧美一区二区三区另类精品| 一区二区精品在线| 欧美国产丝袜视频| 亚洲国产精品一区二区www| 久久国产日韩| 国产日韩视频一区二区三区| 亚洲一区综合| 国产精品久久二区| 亚洲一区二区精品| 欧美天天在线| 亚洲网站视频| 国产精品视频区| 午夜日韩在线观看| 国产农村妇女精品一二区| 亚洲欧美日本另类| 国产毛片久久| 久久精品国产在热久久| 一区二区亚洲精品| 欧美精品电影| 亚洲欧美电影院| 国产主播一区二区| 欧美成ee人免费视频| 亚洲视频网站在线观看| 国产精品影片在线观看| 久久久精品性| 99国产精品99久久久久久| 欧美网站在线| 久久久久久97三级| 99re6这里只有精品| 国产深夜精品| 欧美日本一区| 久久精品日产第一区二区| 在线成人av| 国产精品久久国产精品99gif | 在线成人激情| 欧美日韩伊人| 久久久久久亚洲精品杨幂换脸| 亚洲国产婷婷香蕉久久久久久99 | 欧美视频一区二区在线观看| 欧美一区在线视频| 亚洲精品网址在线观看| 国产美女精品在线| 欧美日韩国产成人在线91| 午夜精品视频在线| 亚洲免费av电影| 狠狠干综合网| 国产精品永久| 国产精品99一区| 欧美激情国产精品| 久久人人爽人人爽| 欧美一区二区高清| 亚洲午夜精品视频| 9人人澡人人爽人人精品| 激情综合亚洲| 国产欧美精品| 国产精品视频网址| 合欧美一区二区三区| 欧美性理论片在线观看片免费| 91久久久久久久久| 欧美成人免费在线| 亚洲精品久久| 国产精品久久久久久av下载红粉| 亚洲欧洲一区二区天堂久久 | 日韩视频不卡| 牛牛精品成人免费视频| 国产亚洲精品7777| 欧美xxx在线观看| 亚洲一区免费在线观看| 美女成人午夜| 久久久99国产精品免费| 欧美亚洲系列| 久久精品视频免费播放| 久久另类ts人妖一区二区| 久久国产福利国产秒拍| 欧美在线视频免费播放| 香蕉久久夜色精品| 亚洲手机视频| 亚洲精品乱码久久久久久| 亚洲激情社区| 亚洲理论在线观看| 亚洲美女福利视频网站| 在线综合亚洲欧美在线视频| 亚洲欧美国产高清va在线播| 欧美亚洲在线| 麻豆精品视频在线| 欧美日韩国产综合视频在线| 国产精品亚洲综合| 激情文学综合丁香| 亚洲老司机av| 亚洲网友自拍| 美女精品在线| 欧美日韩亚洲精品内裤| 欧美涩涩视频| 国语自产偷拍精品视频偷| 亚洲激情在线| 一区二区免费看| 久久精品国产99| 欧美日本一区| 激情综合色综合久久| 亚洲视频www| 美女福利精品视频| 国产精品theporn| 一区二区三区在线观看视频| 亚洲精品之草原avav久久| 亚洲少妇一区| 老司机久久99久久精品播放免费 | 性8sex亚洲区入口| 久久久久91| 欧美三级欧美一级| 国产偷国产偷亚洲高清97cao| 亚洲国产欧美一区| 香蕉久久夜色精品国产| 欧美理论电影在线播放| 亚洲国产精品va| 午夜精品视频在线观看| 欧美另类变人与禽xxxxx| 狠狠色丁香久久婷婷综合丁香| 一本色道久久综合| 老司机免费视频久久| 国产亚洲日本欧美韩国| 亚洲影视中文字幕| 欧美人与性动交a欧美精品| 影音先锋久久久| 久久精品99无色码中文字幕| 国产精品女主播| 一区二区精品在线| 欧美日韩国产一区精品一区 | 最新热久久免费视频| 久久精品国语| 国产一区亚洲| 久久精品在这里| 国内揄拍国内精品久久| 欧美永久精品| 伊人久久噜噜噜躁狠狠躁| 猛干欧美女孩| 亚洲日本成人| 久久中文字幕一区| 黄色一区二区三区四区| 久久久精品性| 一区二区在线观看视频| 久久先锋影音av| 性做久久久久久久久| 老司机精品视频一区二区三区| 国产欧美一区二区精品婷婷| 欧美亚洲网站| 亚洲天堂激情| 久久在线视频在线| 亚洲成人在线网站| 欧美精品自拍| 亚洲欧美另类国产| 好看的日韩视频| 免费在线看成人av| 一区二区三区精品视频在线观看| 国产精品久久久一区二区| 久久久999精品| 99精品久久久| 国产一区二区三区丝袜| 欧美精品一区二区久久婷婷| 欧美亚洲综合在线| 亚洲精品国产精品国自产观看浪潮 | 欧美一区二区三区的| 欧美亚洲日本国产| 国产精品久久久91| 99在线|亚洲一区二区| 久久久久久有精品国产| 伊甸园精品99久久久久久| 亚洲一区二区成人在线观看| 欧美日韩综合不卡| 日韩视频一区|