1. 程式人生 > >buildroot構建項目(三)--- u-boot 2017.11 適配開發板修改 1

buildroot構建項目(三)--- u-boot 2017.11 適配開發板修改 1

型號 mmu mman body 成功 -c 存儲器 介紹 我們

  當前雖然編譯成功了,但是對於我們自己的目標板並不太適用。還得做一系列得修改。

一、lds 文件分析

  u-boot 中最重要得鏈接文件即是,u-boot.lds。我們可以查看我們編譯出來得 u-boot.lds 文件進行分析,原始文件在 arch/arm/cpu/ 下,編譯出來得去掉了不想關得選項。

  u-boot.lds腳本文件告訴鏈接器linker如何布局代碼段、數據段、bss段等,已經配置了u-boot自拷貝(從flash到RAM的copy)的內容。另外,還簡要的涉及了動態鏈接技術等。

  1 /* 指定輸出的可執行文件 elf 格式,32位,小端  */
  2 OUTPUT_FORMAT("
elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 3 /* 指定輸出可執行文件的平臺為 arm */ 4 OUTPUT_ARCH(arm) 5 /* 指定輸出可執行文件的起始代碼段為_start */ 6 ENTRY(_start) 7 /* 指定可執行文件的全局入口點,通常這個地址都放在ROM(flash)0x0位置。 8 * 必須使編譯器知道這個地址 */ 9 SECTIONS 10 { 11 /* 從0x0位置開始 */ 12 . = 0x00000000; 13 /* 代碼以4字節對齊 */ 14 . = ALIGN(4
); 15 /* 代碼段 */ 16 .text : 17 { 18 /* u-boot將自己copy到RAM,此為需要copy的程序的start */ 19 *(.__image_copy_start) 20 /* ./arch/arm/lib/vectors.S,異常向量表 */ 21 *(.vectors) 22 /* ./arch/arm/cpu/arm920t/start.S */ 23 arch/arm/cpu/arm920t/start.o (.text*) 24 /* 其他的代碼段放在這裏,即 start.S/vector.S 之後
*/ 25 *(.text*) 26 } 27 /* 代碼段結束後,有可能4bytes不對齊了,此時做好4bytes對齊,以開始後面的.rodata段 */ 28 . = ALIGN(4); 29 /* 在代碼段之後,存放read only數據段 */ 30 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } 31 /* 4bytes對齊,以開始接下來的.data段 */ 32 . = ALIGN(4); 33 /* 可讀寫數據段 */ 34 .data : { 35 *(.data*) 36 } 37 /* 4字節對齊 */ 38 . = ALIGN(4); 39 /* 當前地址為4字節對齊後的地址 */ 40 . = .; 41 /* 4字節對齊 */ 42 . = ALIGN(4); 43 /* .data段結束後,緊接著存放u-boot自有的一些function,例如u-boot command等 */ 44 .u_boot_list : { 45 KEEP(*(SORT(.u_boot_list*))); 46 } 47 . = ALIGN(4); 48 /* UEFI支持, */ 49 .__efi_runtime_start : { 50 *(.__efi_runtime_start) 51 } 52 /* */ 53 .efi_runtime : { 54 *(efi_runtime_text) 55 *(efi_runtime_data) 56 } 57 /* */ 58 .__efi_runtime_stop : { 59 *(.__efi_runtime_stop) 60 } 61 /* */ 62 .efi_runtime_rel_start : 63 { 64 *(.__efi_runtime_rel_start) 65 } 66 /* */ 67 .efi_runtime_rel : { 68 *(.relefi_runtime_text) 69 *(.relefi_runtime_data) 70 } 71 /* UEFI結束 */ 72 .efi_runtime_rel_stop : 73 { 74 *(.__efi_runtime_rel_stop) 75 } 76 /* 4字節對齊 */ 77 . = ALIGN(4); 78 /* 至此,u-boot需要自拷貝的內容結束,總結一下,包括代碼段,數據段,以及u_boot_list */ 79 .image_copy_end : 80 { 81 *(.__image_copy_end) 82 } 83 /* 在老的uboot中,如果我們想要uboot啟動後把自己拷貝到內存中的某個地方,只要把要拷貝的地址寫給TEXT_BASE即可, 84 * 然後boot啟動後就會把自己拷貝到TEXT_BASE內的地址處運行,在拷貝之前的代碼都是相對的,不能出現絕對的跳轉,否則會跑飛。 85 * 在新版的uboot裏,TEXT_BASE的含義改變了。它表示用戶要把這段代碼加載到哪裏,通常是通過串口等工具。 86 * 然後搬移的時候由uboot自己計算一個地址來進行搬移。新版的uboot采用了動態鏈接技術,在lds文件中有__rel_dyn_start和__rel_dyn_end, 87 * 這兩個符號之間的區域存放著動態鏈接符號,只要給這裏面的符號加上一定的偏移,拷貝到內存中代碼的後面相應的位置處, 88 * 就可以在絕對跳轉中找到正確的函數。 */ 89 .rel_dyn_start : 90 { 91 *(.__rel_dyn_start) 92 } 93 /* 動態鏈接符存放在的段 */ 94 .rel.dyn : { 95 *(.rel*) 96 } 97 /* 動態鏈接符段結束 */ 98 .rel_dyn_end : 99 { 100 *(.__rel_dyn_end) 101 } 102 .end : 103 { 104 *(.__end) 105 } 106 /* bin文件結束 */ 107 _image_binary_end = .; 108 . = ALIGN(4096); 109 .mmutable : { 110 *(.mmutable) 111 } 112 113 /* .bss節包含了程序中所有未初始化的全局變量 */ 114 .bss_start __rel_dyn_start (OVERLAY) : { 115 KEEP(*(.__bss_start)); 116 __bss_base = .; 117 } 118 .bss __bss_base (OVERLAY) : { 119 *(.bss*) 120 . = ALIGN(4); 121 __bss_limit = .; 122 } 123 /* bss段結束 */ 124 .bss_end __bss_limit (OVERLAY) : { 125 KEEP(*(.__bss_end)); 126 } 127 128 .dynsym _image_binary_end : { *(.dynsym) } 129 .dynbss : { *(.dynbss) } 130 .dynstr : { *(.dynstr*) } 131 .dynamic : { *(.dynamic*) } 132 .plt : { *(.plt*) } 133 .interp : { *(.interp*) } 134 .gnu.hash : { *(.gnu.hash) } 135 .gnu : { *(.gnu*) } 136 .ARM.exidx : { *(.ARM.exidx*) } 137 .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) } 138 }

二、norflash 介紹

  ARM的啟動都是從0地址開始,所不同的是地址的映射不一樣。在 arm 上電的時候,要想讓 arm 知道以某種方式(地址映射方式)運行,不可能通過你寫的某段程序控制,因為這時候你的程序還沒啟動,這時候arm會通過引腳的電平來判斷。

2.1 硬件

2.1.1 存儲器地址

  s3c2440 的存儲器控制器為訪問外部存儲的需要器提供了存儲器控制信號。 存儲器控制器的地址空間總共有 8 個 bank,每個bank 為128M,總共為1G。除了 BANK016/32 位)之外,其它全部 BANK 都可編程訪問位寬(8/16/32 位)

  • 8 個存儲器 Bank
    • 6 個存儲器 Bank ROMSRAM
    • 其余 2 個存儲器 Bank ROMSRAMSDRAM
    • 7 個固定的存儲器 Bank 起始地址
    • 1 個可變的存儲器 Bank 起始地址並 Bank 大小可編程
    • 所有存儲器 Bank 的訪問周期可編程

  技術分享圖片

  • OM管腳是使能NAND Flash 的管腳,當OM=00時,是表示使用 NAND Flash 為引導 ROM。
  • nGCS0 為片選信號控制
  • 0x0000_0000 這些為存儲器地址。
  • BANK 6 BANK 7 必須為相同的存儲器大小

2.1.2 OM管腳

  OM有兩個管腳,用來控制存儲器。

  技術分享圖片

  BANK0nGCS0)的數據總線應當配置為 16 位或 32 位的寬度。因為 BANK0 是作為引導 ROM bank(映射到 0x0000_0000),應當在第一個 ROM 訪問前決定 BANK0 的總線寬度,其依賴於復位時 OM[1:0]的邏輯電平。

2.1.3 存儲器概念

  • SDRAM(Synchronous Dynamic Random Access Memory):同步動態隨機存取存儲器,
    • 同步是指Memory工作需要步時鐘,內部的命令的發送與數據的傳輸都以它為基準;
    • 動態是指存儲陣列需要不斷的刷新來保證數據不丟失;
    • 隨機是指數據不是線性依次存儲,而是由指定地址進行數據讀寫,簡單的說,它就是cpu使用的外部內存,即我們常說的內存條。
    • 主要用於程序執行時的程序存儲、執行或計算
  • SRAM是英文Static RAM的縮寫,它是一種具有靜止存取功能的內存,不需要刷新電路即能保存它內部存儲的數據,速度比SDRAM快,一般用作高速緩沖存儲器(Cache)。
  • norflash:非易失閃存,是一種外部存儲介質,芯片內執行(XIP,eXecute In Place),這樣應用程序可以直接在flash閃存內運行,不必再把代碼讀到系統RAM中,
    • 由於它有地址總線,cpu可以直接從norflash中取指,直接從FLASH中運行程序,但是工藝復雜,價格比較貴,容量較小(1~4M),NOR的傳輸效率很高,擦初和寫操作效率很低
  • nandflash:它也是非易失閃存(掉電不丟失)的一種,但是它雖然有數據總線,但是沒有地址總線,所以cpu不能直接從nandflash中取指運行,由於它價格便宜,所以常常用來存儲大量數據,和我們常說的硬盤類似。

2.2 norflash 啟動

  • S3C2440的啟動時讀取的第一條指令是在0x00上,分別為nand flash和nor flash上啟動。
  • Nor flash的有自己的地址線和數據線,可以采用類似於memory的隨機訪問方式,在nor flash上可以直接運行程序,所以nor flash可以直接用來做 boot,采用 nor flash 啟動的時候會把地址映射到 0x00 上。  
  • 任何flash器件的寫入操作只能在空或已擦除的單元內進行
    • 擦除NOR器件時是以64~128KB的塊進行的,執行一個寫入/擦除操作的時間為5s,NORFLASHSECTOR擦除時間視品牌、大小不同而不同,比如,4MFLASH,有的SECTOR擦除時間為60ms,而有的需要最大6S 
  • Nand flash是IO設備,數據、地址、控制線都是共用的,需要軟件區控制讀取時序,所以不能像nor flash、內存一樣隨機訪問,不能EIP(片上運行),因此不能直接作為boot。
  • 在u-boot 啟動中,需要把 程序拷貝到 SDRAM中去運行,也可以不用拷貝。
  • nor 啟動的時候,CPU的0地址就指向 norflash

  技術分享圖片

2.2.1 norflash 電路

  運行的目標開發板為 JZ2440 開發板。norflash 型號為 MX29LV160DBTI,16M存儲空間,

  技術分享圖片

2.2.2 代碼修改

  

  

  

buildroot構建項目(三)--- u-boot 2017.11 適配開發板修改 1