嵌入式開發(fā)】 Bootloader 詳解 ( 代碼環(huán)境 | ARM 啟動流程 | uboot 工作流程 | 架構(gòu)設(shè)計)

      網(wǎng)友投稿 1385 2025-04-01

      博客地址 :?http://blog.csdn.net/shulianghan/article/details/42462795

      轉(zhuǎn)載請著名出處

      相關(guān)資源下載 :

      -- u-boot 源碼 :?http://download.csdn.net/detail/han1202012/8342761

      -- S3C2440 文檔 :?http://download.csdn.net/detail/han1202012/8342701

      --?S5PV210_iROM_ApplicationNote_Preliminary_20091126 文檔 :?http://download.csdn.net/detail/han1202012/8342709

      -- S3C6410_Internal_ROM_Bootin 文檔?:?http://download.csdn.net/detail/han1202012/8342725

      -- S3C6410X 文檔?:?http://download.csdn.net/detail/han1202012/8342731

      --?S5PV210_UM_REV1.1 文檔 :?http://download.csdn.net/detail/han1202012/8342745

      一. Bootloader 簡介

      1. Bootloader 簡介

      Bootloader 作用 : 啟動系統(tǒng)時將 Kernel 帶入到內(nèi)存中, 之后 Bootloader 就沒有用處了;

      -- Bootloader 在 Linux 系統(tǒng)中的層次 : Bootloader --> Boot parameters --> Kernel --> root filesystems;

      -- 最常用的 bootloader : uboot 是 bootloader 中最優(yōu)秀的;

      uboot 簡介 :

      -- 支持 CPU : MIPS, x86, ARM 等;

      -- 引導(dǎo)的系統(tǒng) : Linux, Android, VxWorks, QNX;

      uboot 模式 :

      -- 自主模式 : 如果開機(jī), 我們什么操作都不做就是自主模式;

      -- 開發(fā)模式 : 開機(jī)后立刻按下 空格鍵, 會進(jìn)入 uboot 的命令行模式, 即開發(fā)模式;

      2. 使用 Source Insight 閱讀 uboot 源碼

      Source Insight 使用流程 :

      -- 創(chuàng)建工程 : "菜單欄" --> "Project" --> New Project 彈出下面的對話框, 在對話框中輸入代碼的保存路徑 和 工程名;

      -- 每個工程有自己的文件 : 點(diǎn)擊 OK 后, 在下面的對話框選擇第一個選項, 其它默認(rèn);

      -- 彈出選擇源碼界面 : 這里現(xiàn)在這里暫停下, 也可以關(guān)掉, 從 "菜單" --> "Project" --> "Add and Remove Project Files";

      -- 解壓 uboot 源碼 : 使用 Samba 文件共享, 將 uboot 源碼在 linux 目錄下解壓, 由于編碼和文件系統(tǒng)特性, 在 windows 目錄下解壓會出錯, 通過 直接在 Samba 用戶目錄下解壓;

      [root@localhost arm]# cd /home/samba/ [root@localhost samba]# ls ARM-tools uboot.tar.gz [root@localhost samba]# [root@localhost samba]# [root@localhost samba]# tar -xvzf uboot.tar.gz uboot/ uboot/README ... ...

      -- 添加映射地址 : 在映射網(wǎng)絡(luò)驅(qū)動器對話框中, 填入 Samba 目錄;

      -- 生成了一個 Z 盤 :

      -- 導(dǎo)入代碼 : 選擇 "菜單" --> "Project" -->?"Add and Remove Project Files", 在彈出的對話框中選中 uboot 目錄, 并進(jìn)入其跟目錄, 選擇 右側(cè) "Add all" 按鈕, 在彈出的對話框中選擇兩個選項都選擇, 以便其子目錄中的文件也能被加載進(jìn)入;

      -- 查看加載完成的工程 : 發(fā)現(xiàn)沒有 .S 匯編文件;

      -- 加載匯編文件 : 選擇 ?"菜單" --> "Options" --> "Document Options", 在 C Source File 中選擇 *.s;*.S, 結(jié)果為 "*.c;*.h;*.s;*.S";

      -- 繼續(xù)添加工程文件 : 選擇 "菜單" --> "Project" --> "Add and Remove Project file";

      -- 此時匯編文件出現(xiàn)了 :

      二. ARM 處理器啟動流程 (啟動方式 | 內(nèi)存映射 | 啟動流程)

      1. S3C2440 芯片啟動流程

      (1) S3C2440 啟動方式

      2440 啟動方式 :

      -- Nor Flash : Nor Flash 大小只有 2M;

      -- Nand Flash : Nand Flash 大小 256M;

      (2) S3C2440 內(nèi)存映射

      內(nèi)存映射?: S3C2440 文檔, Page 221, 第六章 Nand Flash Memory Mapping, 也可以搜索 Mapping 關(guān)鍵詞;

      --?左圖?: Nor Flash 啟動地址映射;

      --?右圖?: Nand Flash 啟動地址映射;

      (3) S3C2440 啟動流程

      Nor Flash 指令加載?:??CPU 上電 讀取指令 : 從 0x0 地址讀取指令;

      Nand Flash 指令加載?:

      --?啟動 0 地址?: Nand Flash 不能被直接訪問到, 沒有參與 ARM 的編址, BootSRAM 是片內(nèi)的 RAM;

      --?BootRAM 簡介?: BootSRAM 又名 Setpping stone (墊腳石), Bootloader 最前端 4K 自動復(fù)制到 BootRAM, 剩下的 復(fù)制到 內(nèi)存中, 4K 的代碼運(yùn)行完之后會跳轉(zhuǎn)到內(nèi)存繼續(xù)執(zhí)行剩下的代碼;

      --?內(nèi)存地址?: 在下面的 Nand Flash Memory Mapping 圖中, s3c2440 芯片內(nèi)存起始地址是 0x3000_0000;

      --?文檔參考?: Page 213, 章節(jié)6 Nand Flash Contorller;

      OVERVIEW In recent times, NOR flash memory gets high in price while an SDRAM and a NAND flash memory is comparatively economical , motivating some users to execute the boot code on a NAND flash and execute the main code on an SDRAM. S3C2440A boot code can be executed on an external NAND flash memory. In order to support NAND flash boot loader, the S3C2440A is equipped with an internal SRAM buffer called ‘Steppingstone’. When booting, the first 4 KBytes of the NAND flash memory will be loaded into Steppingstone and the boot code loaded into Steppingstone will be executed. Generally, the boot code will copy NAND flash content to SDRAM. Using hardware ECC, the NAND flash data validity will be checked. Upon the completion of the copy, the main program will be executed on the SDRAM.

      2. S3C6410 芯片啟動流程

      (1) S3C6410 啟動方式

      s3c6410 啟動方式介紹 :

      -- SROM 啟動 : 即 Nor Flash 啟動, 6410 也支持 Nor Flash 啟動;

      -- OneNand 啟動 : 特殊的 Nand Flash, 同時具有 Nor Flash 和 Nand Flash 的特性;

      -- MODEM 啟動 : ?詳情參考文檔;

      -- IROM 啟動 : IROM 是處理器內(nèi)部的組件, 該啟動方式包括 SD 卡啟動 和 Nand Flash 啟動;

      --?啟動方式文檔 : S3C6410X 文檔,?搜索關(guān)鍵詞 booting, Page 123, 3.3.3 章節(jié);

      (2) S3C6410 地址映射

      啟動設(shè)備地址布局 :

      -- IROM (Internal ROM) : 0x0800_000 地址, 64M;

      -- Stepping Stone (Boot Loader) : 0x0C00_0000 地址, 64M;

      --?地址布局文檔 :??S3C6410X 文檔,?Page 116, 2.2 章節(jié), Device Specific Address Space 圖表 設(shè)備特殊地址空間;

      0 地址映射介紹 :

      -- 鏡像區(qū)域 :?Booting Device Region by XOM Setting (XOM設(shè)置的引導(dǎo)設(shè)備區(qū)域), 根據(jù)不同的啟動設(shè)置, 將對應(yīng)的啟動設(shè)備映射到該區(qū)域;

      -- IROM 啟動 : 會將 IROM 映射到該鏡像區(qū)域;

      -- Nor Flash 啟動 : 將 Nor Flash 映射到該鏡像區(qū)域;

      -- 文檔參考 : 從上面的文檔截圖 :

      (3) S3C6410 啟動流程

      啟動流程 :?S3C6410_Internal_ROM_Booting 文檔, Page 6, 2.1 章節(jié);

      -- 1. IROM 初始化 : IROM 中固化了軟件, 稱為 bootloader0, 是 0階段的 bootloader, 該 BL0 執(zhí)行 初始化時鐘, D-TCM, 設(shè)備特殊控制器, 引導(dǎo)設(shè)備;

      -- 2. 加載 BL1 : 加載 BL1 到 Stepping Stone (墊腳石), 將放在 nand flash 中的 bootloader1 (即 Bootloader 最前面的 8K) 拷貝到 Stepping Stone 中;

      -- 3. 執(zhí)行 BL1 : BL1 初始化系統(tǒng)時鐘, UART, SDRAM, Stepping Stone 執(zhí)行完 8K Bootloader 后, 將剩余的 bootloader (BL2) 拷貝到 SDRAM 中運(yùn)行;

      -- 4. 執(zhí)行 BL2 : 跳轉(zhuǎn)到 SDRAM 中執(zhí)行 BL2, 加載內(nèi)核;

      -- 對比 2440 : 上電后 6410 先運(yùn)行 IROM 中的代碼, 不是先運(yùn)行 Bootloader;

      -- 文檔參考 :

      3. S5PV210 芯片啟動流程

      (1) S5PV210啟動方式

      S5PV210 啟動方式簡介 :

      -- IROM 啟動方式 : 包括 Nand Flash 啟動, SD 卡啟動;

      -- First boot URAT --> USB 啟動方式 : USB , 串口等啟動方式;

      -- 文檔位置 : S5PV210_UM_REV1.1 文檔, Page 523, 6.2.4 章節(jié);

      (2) S5PV210地址映射

      S5PV210 地址映射 :

      -- IROM : 首地址 0xD000_0000, 大小 64KB;

      -- IRAM : 這是 Stepping Stone (墊腳石), 首地址?0xD002_0000, 大小 96KB;

      -- 零地址 : Boot area, 是一個映射區(qū)域, 與啟動模式(boot model)相關(guān). 該地址不固定于某一個設(shè)備, 如果使用 IRAM 啟動, 就會將 IRAM 地址映射到 零地址處;

      -- 內(nèi)存 : 內(nèi)存 首地址 0x2000_0000, DRAM0 位置;

      -- 文檔位置 : Page 30, 2.1.1 章節(jié), Device Specific Address Space 表;

      (3) S5PV210啟動過程

      名詞解釋 :

      -- IROM : 引導(dǎo)區(qū)域, 該區(qū)域的鏡像取決與啟動模式, 根據(jù)啟動模式裝載不用的設(shè)備映像到該 IROM 區(qū)域;

      -- I-SRAM | SRAM : 這里的 SRAM 是 Stepping Stone (墊腳石), 用于存放拷貝的 bootloader 第一 和 第二階段的代碼;

      -- BL1 : bootloader 第一階段;

      -- BL2 : bootloader 第二階段;

      --?SDRAM Controller : 內(nèi)存控制器;

      -- SDRAM | DRAM : 內(nèi)存;

      S5PV210 啟動過程 :

      -- 1. IROM 初始化 : 初始化系統(tǒng)時鐘, 初始化設(shè)備特別控制器, 引導(dǎo)設(shè)備;

      -- 2. 裝載 BL1 : 將 BL1 (16KB) 拷貝到 IRAM (Strpping Stone 96KB 明顯比arm11 要大) 中, IROM 會在安全引導(dǎo)模式下驗(yàn)證 BL1 完整性;

      -- 3. 執(zhí)行 BL1 : 將 BL2 (80KB) 拷貝到 I-SRAM (Internal 內(nèi)部 SRAM ) 中, BL1 會在安全引導(dǎo)模式下驗(yàn)證 BL2 完整性;

      -- 4. 執(zhí)行 BL2 : 初始化內(nèi)存控制器,?如果 Stepping Stone 還不夠, 那么就將剩余的拷貝到 SDRAM(內(nèi)存) 中, 然后裝載操作系統(tǒng)到內(nèi)存中;

      -- 5. 執(zhí)行操作系統(tǒng) : 跳轉(zhuǎn)到內(nèi)存中, 執(zhí)行 剩余的 BL 或者 執(zhí)行操作系統(tǒng)代碼;

      -- 參考文檔 :?S5PV210_iROM_ApplicationNote_Preliminary_20091126 文檔, Page 7, 2.1 章節(jié), Operating Sequence 圖;

      博客地址?:?http://blog.csdn.net/shulianghan/article/details/42462795

      轉(zhuǎn)載請著名出處

      相關(guān)資源下載?:

      --?u-boot 源碼?:?http://download.csdn.net/detail/han1202012/8342761

      --?S3C2440 文檔?:?http://download.csdn.net/detail/han1202012/8342701

      --?S5PV210_iROM_ApplicationNote_Preliminary_20091126 文檔?:?http://download.csdn.net/detail/han1202012/8342709

      --?S3C6410_Internal_ROM_Bootin 文檔?:?http://download.csdn.net/detail/han1202012/8342725

      --?S3C6410X 文檔?:?http://download.csdn.net/detail/han1202012/8342731

      --?S5PV210_UM_REV1.1 文檔?:?http://download.csdn.net/detail/han1202012/8342745

      三. U-Boot 工作流程詳解

      1. S3C2440 芯片的 U-Boot 工作流程

      (1) S3C2440 BL 程序入口

      S3C2440 uboot 入口分析 :

      -- Makefile 分析 : 查看uboot 源碼根目錄下的?Makefile 文件, 可以找到下面的內(nèi)容 :

      smdk2440_config : unconfig @$(MKCONFIG) $(@:_config=) arm s3c24xx smdk2440 samsung s3c2440

      -- 2440 開發(fā)板相關(guān)文件 : 與該芯片對應(yīng)的各種硬件相關(guān)文件在 \board\samsung\smdk2440 目錄, 下面是目錄內(nèi)容;

      [root@localhost uboot]# cd board/samsung/smdk2440/ [root@localhost smdk2440]# ls config.mk libsmdk2440.a Makefile smdk2440_val.h flash.c lowlevel_init.o smdk2440.c u-boot.lds flash.o lowlevel_init.S smdk2440.o

      -- u-boot.lds 鏈接器腳本內(nèi)容 : 分析 "cpu/s3c24xx/start.o (.text)" 內(nèi)容, 可以知道?cpu/s3c24xx/start.o 是程序入口;

      OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/s3c24xx/start.o (.text) cpu/s3c24xx/s3c2440/cpu_init.o (.text) *(.text) } . = ALIGN(4); .rodata : { *(.rodata) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); .got : { *(.got) } . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); .mmudata : { *(.mmudata) } . = ALIGN(4); __bss_start = .; .bss : { *(.bss) } _end = .; }

      /* ************************************************************************* * * Jump vector table as in table 3.1 in [1] * ************************************************************************* */ .globl _start _start: b reset 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 _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 .balignl 16,0xdeadbeef

      (2) S3C2440 BL1 工作流程

      分析 Linux 內(nèi)核 驅(qū)動 Bootloader 原則 :

      -- 先看功能 : 看注釋, 看代碼功能做了什么, 暫時不關(guān)心如何實(shí)現(xiàn)的, 實(shí)現(xiàn)細(xì)節(jié)最后看;

      BL1 階段代碼分析 :

      -- 設(shè)置中斷向量表 : Line 63;

      /* ************************************************************************* * * Jump vector table as in table 3.1 in [1] * ************************************************************************* */ .globl _start _start: b reset 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

      reset: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0

      /* * we do sys-critical inits only at reboot, * not when booting from ram! */ cpu_init_crit: /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

      /* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */

      /* * Go setup Memory and board specific bits prior to relocation. */ bl lowlevel_init /* go setup pll,mux,memory */

      -- 關(guān)閉看門狗 : lowlevel_init.S?Line 79;

      /* Disable Watchdog */ ldr r0, =ELFIN_WATCHDOG_BASE mov r1, #0 str r1, [r0]

      -- 關(guān)閉所有中斷 :?lowlevel_init.S?Line 85;

      /* mask all IRQs by setting all bits in the INTMR - default */ ldr r0, =ELFIN_INTERRUPT_BASE mov r1, #0xffffffff str r1, [r0, #INTMSK_OFFSET] ldr r1, =0x000007ff str r1, [r0, #INTSUBMSK_OFFSET]

      -- 初始化系統(tǒng)時鐘 : 在?lowlevel_init.S 中定義的?lowlevel_init 方法, Line 45;

      /* init system clock */ bl system_clock_init

      /* for UART */ bl uart_asm_init

      /* simple init for NAND */ bl nand_asm_init

      /* when we already run in ram, we don't need to relocate U-Boot. * and actually, memory controller must be configured before U-Boot * is running in ram. */ ldr r0, =0xf0000fff bic r1, pc, r0 /* r0 <- current base addr of code */ ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */ bic r2, r2, r0 /* r0 <- current base addr of code */ cmp r1, r2 /* compare r0, r1 */ beq 1f /* r0 == r1 then skip sdram init */ adrl r0, mem_cfg_val bl mem_con_init

      1: mov lr, r12 mov pc, lr

      /* check boot device is nand or nor */ ldr r0, =0x00000000 ldr r3, [r0] ldr r1, =0xfffffffe str r1, [r0] ldr r2, [r0] str r3, [r0] cmp r1, r2

      nand_copy: mov r0, #0x1000 bl copy_from_nand

      /* Set up the stack */ stack_setup:

      clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */

      -- 跳轉(zhuǎn)到 arm_boot : PC 指針跳轉(zhuǎn)到?_start_armboot 函數(shù)運(yùn)行;

      ldr pc, _start_armboot _start_armboot: .word start_armboot

      void start_armboot (void) { init_fnc_t **init_fnc_ptr; char *s;

      (3) S3C2440 BL2 工作流程

      分析 BL2 執(zhí)行流程 :

      -- BL2 程序入口 : /lib_arm/board.c 中的 Line 268,?start_armboot 函數(shù), 在這個函數(shù)中執(zhí)行了一個循環(huán) :

      for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } }

      --?init_sequence 指針函數(shù) 數(shù)組定義 :

      init_fnc_t *init_sequence[] = { cpu_init, /* basic cpu dependent setup */ board_init, /* basic board dependent setup */ interrupt_init, /* set up exceptions */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ #if defined(CONFIG_DISPLAY_CPUINFO) print_cpuinfo, /* display cpu info (and speed) */ #endif #if defined(CONFIG_DISPLAY_BOARDINFO) checkboard, /* display board info */ #endif dram_init, /* configure available RAM banks */ display_dram_config, NULL, };

      -- lcd 初始化 : Line 344 行定義;

      size = lcd_setmem (addr);

      -- 初始化 led : Line 487, "led_init(); ? ? /*led all off --forlinx add */";

      -- 執(zhí)行用戶輸入命令 : 初始化 led 之后進(jìn)入主循環(huán), main_loop 解析用戶控制臺輸入命令解析, 并執(zhí)行用戶輸入的命令;

      led_init(); /*led all off --forlinx add */ /* main_loop() can return to retry autoboot, if so just run it again. */ for (;;) { main_loop (); } /* NOTREACHED - no way out of command loop except booting */

      2. S3C2440 芯片 u-boot 分析

      (1) S3C2440 uboot 配置編譯

      uboot 配置和編譯 :

      -- 找到 Makefile 中的 2440 目標(biāo)項 : 目標(biāo)是?smdk2440_config;

      smdk2440_config : unconfig @$(MKCONFIG) $(@:_config=) arm s3c24xx smdk2440 samsung s3c2440

      -- 配置編譯環(huán)境 : 執(zhí)行 make?smdk2440_config 命令;

      [root@localhost uboot]# make smdk2440_config Configuring for smdk2440 board which boot from ...

      -- 反編譯 u-boot elf 文件 : 使用?arm-linux-objdump -S -D u-boot > uboot_dump 命令, 反編譯, 分析反編譯結(jié)果 :

      [root@localhost uboot]# arm-linux-objdump -S -D u-boot > uboot_dump [root@localhost uboot]# gedit uboot_dump 30009100 : NULL, }; void start_armboot (void) { 30009100: e92d4070 push {r4, r5, r6, lr} gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t); #ifdef CONFIG_USE_IRQ gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ); #endif gd = (gd_t*)gd_base; 30009104: e59f8190 ldr r8, [pc, #400] ; 3000929c NULL, };

      (2) S3C2440 uboot 鏈接地址分析

      鏈接地址分析 :

      -- 查看連接器腳本 : 查看 /board/samsung/smdk2440/u-boot.lds 鏈接器腳本, 代碼段的起始地址是?0x00000000;

      OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/s3c24xx/start.o (.text) cpu/s3c24xx/s3c2440/cpu_init.o (.text) *(.text) } ... ...

      --?TEXT_BASE 變量定義?: 在 /board/samsung/smdk2440/config.mk 中?"TEXT_BASE = 0x30008000" 定義了該變量;

      -- 查看反編譯中的地址 : 代碼的起始地址果然是 30008000;

      octopus@octopus:~/arm/uboot/uboot$ more uboot_dump u-boot: file format elf32-littlearm Disassembly of section .text: 30008000 <_start>: */ .globl _start _start: b reset 30008000: ea000013 b 30008054 ldr pc, _undefined_instruction 30008004: e59ff014 ldr pc, [pc, #20] ; 30008020 <_undefined_instruction> ldr pc, _software_interrupt 30008008: e59ff014 ldr pc, [pc, #20] ; 30008024 <_software_interrupt> ldr pc, _prefetch_abort 3000800c: e59ff014 ldr pc, [pc, #20] ; 30008028 <_prefetch_abort> ldr pc, _data_abort 30008010: e59ff014 ldr pc, [pc, #20] ; 3000802c <_data_abort> ldr pc, _not_used 30008014: e59ff014 ldr pc, [pc, #20] ; 30008030 <_not_used> ldr pc, _irq 30008018: e59ff014 ldr pc, [pc, #20] ; 30008034 <_irq>

      (3) S3C2440 uboot 中的相對地址跳轉(zhuǎn) 和 絕對地址跳轉(zhuǎn)

      相對地址和絕對地址跳轉(zhuǎn) :

      -- 相對跳轉(zhuǎn) : 不會對 PC 造成實(shí)質(zhì)性的影響, B 指令, 首先計算一個相對值, 在 PC 原有基礎(chǔ)上;

      -- 相對跳轉(zhuǎn)示例 : 如 之前的初始化的方法 "bl lowlevel_init", 該行代碼的地址是 0x30008000,?lowlevel_init 在 0x30008010 地址處, 執(zhí)行到了該行代碼,?30008010 是鏈接地址, 但是此時 PC 指針指向的值 還在 墊腳石中, 小于4K, 如此時 PC = 100, 如果進(jìn)行鏈接地址跳轉(zhuǎn) PC = 100 + (0x30008010 - 300080000) 地址, 之后 PC = 110, PC 還是在墊腳石中, 相對地址跳轉(zhuǎn)不會對 PC 造成實(shí)質(zhì)性的影響;

      -- 絕對跳轉(zhuǎn) : 直接修改 PC 指針的值, PC 直接跳到內(nèi)存中, ldr pc #0x30008010, PC 就會編程 0x30008010;

      (4) S3C2440 內(nèi)存分布角度分析啟動流程

      內(nèi)存分布角度分析啟動流程 :

      -- arm 內(nèi)存前 4K : 內(nèi)存中前 4K 是 Stepping Stone;

      -- 拷貝 BL1 : 啟動時, 會將 Nand Flash 拷貝到 Stepping Stone 中, 主要是將 start.S 拷貝進(jìn)去;

      -- 執(zhí)行 BL1 : 之后執(zhí)行 start.S 的 _start 開始執(zhí)行;

      -- 拷貝 BL2 : 執(zhí)行到 BL1 最后會將 BL2 代碼拷貝到內(nèi)存中去;

      -- 執(zhí)行 BL2 : BL1 執(zhí)行完后, PC 指針會跳轉(zhuǎn)到內(nèi)存中接著運(yùn)行 BL2 的代碼;

      (5) S3C2440 地址跳轉(zhuǎn)角度分析啟動流程

      -- arm 地址空間 : 前面 4K 是 Stepping Stone (墊腳石);

      -- nand flash 地址空間 : 前 4K 會被復(fù)制到墊腳石中;

      -- PC 指針 : 此時 PC 指針指向 0, 會取 arm 中的 墊腳石中的指令, 執(zhí)行這些指令;

      -- 拷貝剩余 BL : 執(zhí)行到一定程度, 會將 nand flash 中的剩余 BL 復(fù)制到 0x30008000 地址;

      -- PC 跳轉(zhuǎn)到內(nèi)存 : PC 跳轉(zhuǎn)到 0x30008000 執(zhí)行, 之前 PC 指針值一直小于 4K, 但是跳轉(zhuǎn)后順便值變成 0x30008000 之后的地址了;

      2. S3C6410 芯片的 U-Boot 工作流程

      (1) S3C6410 BL 程序入口

      S3C6410程序入口分析 :

      -- 分析 Makefile 文件 : Line 1953 處定義了?forlinx_nand_ram256_config 目標(biāo), 對應(yīng)開發(fā)板是 smdk6410;

      forlinx_nand_ram256_config : unconfig @$(MKCONFIG) smdk6410 arm s3c64xx smdk6410 samsung s3c6410 NAND ram256

      -- 分析鏈接器腳本 u-boot.lds : 可以看到程序入口是 cpu/s3c64xx/start.S 匯編文件;

      ... ... SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/s3c64xx/start.o (.text) cpu/s3c64xx/s3c6410/cpu_init.o (.text) cpu/s3c64xx/onenand_cp.o (.text) cpu/s3c64xx/nand_cp.o (.text) cpu/s3c64xx/movi.o (.text) *(.text) lib_arm/div0.o } ... ...

      ... ... .globl _start _start: b reset 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 ... ...

      (2) S3C6410 BL1 流程分析

      S3C6410 BL1 流程分析 :

      -- 初始化向量表 : start.S Line 52;

      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

      /* * the actual reset code */ reset: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0

      /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

      /* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0

      /* Peri port setup */ ldr r0, =0x70000000 orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)

      /* * Go setup Memory and board specific bits prior to relocation. */ bl lowlevel_init /* go setup pll,mux,memory */ /* when we already run in ram, we don't need to relocate U-Boot. * and actually, memory controller must be configured before U-Boot * is running in ram. */

      ... ... .globl lowlevel_init lowlevel_init: mov r12, lr ldr r0, =ELFIN_GPIO_BASE ... ...

      -- LED 點(diǎn)亮 : lowlevel_init.S?Line 62;

      /* LED on only #8 */ ldr r0, =ELFIN_GPIO_BASE ldr r1, =0x00111111 str r1, [r0, #GPMCON_OFFSET] ldr r1, =0x00000555 str r1, [r0, #GPMPUD_OFFSET] ldr r1, =0x002a str r1, [r0, #GPMDAT_OFFSET] ldr r1, =0 /*0x55555555 phantom*/ str r1, [r0, #MEM1DRVCON_OFFSET]

      /* Disable Watchdog */ ldr r0, =0x7e000000 @0x7e004000 orr r0, r0, #0x4000 mov r1, #0 str r1, [r0]

      @ Disable all interrupts (VIC0 and VIC1) mvn r3, #0x0 str r3, [r0, #oINTMSK] str r3, [r1, #oINTMSK]

      /* init system clock */ bl system_clock_init

      -- 初始化串口 :?lowlevel_init.S?Line 113;

      /* for UART */ bl uart_asm_init

      /* simple init for NAND */ bl nand_asm_init

      【嵌入式開發(fā)】 Bootloader 詳解 ( 代碼環(huán)境 | ARM 啟動流程 | uboot 工作流程 | 架構(gòu)設(shè)計)

      mov pc, lr

      #ifdef CONFIG_BOOT_NAND mov r0, #0x1000 bl copy_from_nand

      /* Set up the stack */ stack_setup: #ifdef CONFIG_MEMORY_UPPER_CODE ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc) #else ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ #endif

      clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */

      ldr pc, _start_armboot _start_armboot: .word start_armboot

      3. S5PV210 芯片的 U-Boot 工作流程

      (1) S5PV210 BL1 執(zhí)行流程

      S5VP 210 BL1 流程 :

      -- 1. 設(shè)置中斷向量表;

      -- 2. 設(shè)置 CPU svc 工作模式;

      -- 3. 關(guān)閉 L1 (一級的) I/D Cache 失效;

      -- 4. 關(guān)閉 MMU 和 Cache;

      -- 5. 檢查 reset 狀態(tài);

      -- 6. IO 引腳初始化;

      -- 7. 關(guān)閉看門狗;

      -- 8. SRAM 和 SROM 初始化;

      -- 9. 時鐘初始化;

      -- 10. 內(nèi)存初始化;

      -- 11. UART 簡單初始化;

      -- 12. 取消存儲保護(hù)區(qū);

      -- 13. nand flash 簡單初始化;

      -- 14. 關(guān)閉 ABB;

      -- 15. 設(shè)置堆棧;

      -- 16. 將 BL2 到 RAM 中;

      -- 17. 跳轉(zhuǎn)到 RAM 中 運(yùn)行 BL2;

      (2) S5PV210 BL2 復(fù)制分析

      BL2 復(fù)制相關(guān)問題 :

      -- BL2 復(fù)制到內(nèi)存中什么位置 : 到代碼中尋找, 這個地址在頭文件中定義, 0x23100000 位置;

      -- BL1 如何找到 BL2 : nand flash 寫入后 BL1 與 BL2 間距 是 8KB, BL1 是 16KB + 8KB, BL2 在 24KB 地址開始的位置;

      -- BL2 大小要求 : 復(fù)制 512KB 到內(nèi)存中去;

      (3) S5PV210 BL 啟動分析

      S5PV210 啟動流程 : BL1 和 BL2 在 210 上被劃分成了兩部分;

      -- iROM 映射 : iROM 通過映射 被映射到 arm 0 地址處, 里面是一個固件程序, 是三星燒寫好的;

      -- iRAM 墊腳石 : 96KB, Stepping Stone 墊腳石, 在 irom 上面;

      -- 拷貝 BL1 : iROM 固化程序?qū)?BL1 (16KB) 復(fù)制到 iRAM 中;

      -- 拷貝 BL2 : BL1 在 iRAM 中執(zhí)行, 如果 BL2 小于 80K, 復(fù)制 BL2 到 iRAM 中; 如果 BL2 大于 80K, 復(fù)制 BL2 到 內(nèi)存中; uboot 編譯后大于80K, 因此 BL2 復(fù)制到 內(nèi)存中;

      四. Bootloader 架構(gòu)設(shè)計

      H-Boot BL1 程序設(shè)計 : 匯編代碼編寫;

      -- 1. 核心初始化 : a. 設(shè)置中斷向量表, b. 設(shè)置 CPU svc 模式, c. 關(guān)閉看門狗, d. 關(guān)閉中斷, e. 關(guān)閉 MMU 和 Cache, f. 外設(shè)基地址初始化 (f 為6410獨(dú)有);

      -- 2. C 語言編程環(huán)境設(shè)置 : a. 設(shè)置堆棧, b. 清除 BSS 段;

      -- 3. LED 初始化 ;

      -- 4. 初始化系統(tǒng)時鐘;

      -- 5. 內(nèi)存初始化 : a. 取消存儲保護(hù)區(qū) (a 位 210 獨(dú)有), b. iRAM 和 iROM 初始化 (b 為 210 獨(dú)有);

      -- 6. 復(fù)制 nand flash 到內(nèi)存 : a. 簡單初始化 nand flash, b. 復(fù)制代碼到內(nèi)存, c. 跳轉(zhuǎn)到 BL2 入口;

      H-Boot BL2 程序設(shè)計?: 匯編代碼編寫;

      -- 1. MMU 初始化;

      -- 2. 中斷初始化 : a. 中斷初始化, b. 按鍵初始化;

      -- 3. 初始化串口 : a. 串口初始化, b. 移植 printf 函數(shù);

      -- 4. 網(wǎng)卡初始化;

      -- 5. LCD 初始化 : a. 觸摸板初始化, b. LCD 初始化;

      -- 6. 解析執(zhí)行用戶命令 : a. 移植 TFTP 命令, b. 移植 BOOTM 命令;

      博客地址?:?http://blog.csdn.net/shulianghan/article/details/42462795

      轉(zhuǎn)載請著名出處

      相關(guān)資源下載?:

      --?u-boot 源碼?:?http://download.csdn.net/detail/han1202012/8342761

      --?S3C2440 文檔?:?http://download.csdn.net/detail/han1202012/8342701

      --?S5PV210_iROM_ApplicationNote_Preliminary_20091126 文檔?:?http://download.csdn.net/detail/han1202012/8342709

      --?S3C6410_Internal_ROM_Bootin 文檔?:?http://download.csdn.net/detail/han1202012/8342725

      --?S3C6410X 文檔?:?http://download.csdn.net/detail/han1202012/8342731

      --?S5PV210_UM_REV1.1 文檔?:?http://download.csdn.net/detail/han1202012/8342745

      ARM 嵌入式 架構(gòu)設(shè)計

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel調(diào)整圖表的三維視圖格式
      下一篇:WPS表格壓縮圖片的方法步驟詳解(wps如何壓縮excel中的圖片)
      相關(guān)文章
      亚洲人成图片网站| 亚洲AV无码国产精品色午友在线| 亚洲av无码成h人动漫无遮挡| 亚洲国产精品激情在线观看 | 日韩成人精品日本亚洲| 亚洲国产成人超福利久久精品| 亚洲国产二区三区久久| 亚洲AV无码第一区二区三区| 久久综合九九亚洲一区| 久久精品国产亚洲麻豆| 人人狠狠综合久久亚洲婷婷| 亚洲av无码片在线播放| 亚洲电影一区二区三区| 亚洲伊人tv综合网色| 91在线精品亚洲一区二区| 亚洲欧洲校园自拍都市| 亚洲噜噜噜噜噜影院在线播放| 亚洲成人福利在线| 国产婷婷综合丁香亚洲欧洲| 中文字幕在线观看亚洲视频| 精品日韩99亚洲的在线发布| 最新亚洲精品国偷自产在线| 亚洲一区二区三区丝袜| 亚洲av午夜国产精品无码中文字 | 亚洲娇小性xxxx色| 国产亚洲sss在线播放| 亚洲另类无码专区首页| 极品色天使在线婷婷天堂亚洲| 亚洲AV无码乱码在线观看牲色| 亚洲无码精品浪潮| 亚洲精品蜜桃久久久久久| 久久亚洲国产成人亚| 亚洲福利一区二区三区| 亚洲fuli在线观看| 亚洲av日韩精品久久久久久a| 国产天堂亚洲国产碰碰| 久久久久无码专区亚洲av| 亚洲香蕉成人AV网站在线观看| 亚洲AV无码久久精品成人| 91亚洲国产成人久久精品网站| 亚洲同性男gay网站在线观看|