日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Bootloader加载过程分析

發布時間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Bootloader加载过程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注:由于全志A10和A20在加載Bootloader過程方面基本一致,下面僅以A20敘述,但同時也適用于A10。另外在不需要區分Cubieboard1和Cubieboard2的情況下,統稱為Cubieboard;另現在市面上一般所說的SD卡即為Micro SD Card,也就是TF卡,為區別于一般傳統的SD卡,本文一般使用TF卡描述,但同于平時所說的SD卡。

A20的啟動過程大概可分為5步:Boot ROM,SPL,Uboot,Kernel,RootFileSystem。本文關注的是鏡像的加載和啟動過程,分析Boot ROM→SPL→Uboot→Kernel的啟動流程。

系統上電后,ARM處理器在復位時從地址0x000000開始執行指令,把板上ROM或Flash映射到這一地址。A20將啟動設備選擇程序固化在CPU內部的一個32KB ROM中,默認的啟動時序為SD Card0,NAND FLASH,SD Card2,SPI NOR FLASH。另外通過外部的一個啟動選擇引腳可以使其跳轉到USB啟動模式。通常情況下,啟動選擇引腳狀態連接50K內部上拉電阻。在上電后,執行存儲在Boot ROM中的啟動代碼,將自動檢測啟動選擇引腳狀態。只有當該引腳狀態為低電平時才選擇USB啟動模式。

在選擇啟動設備后將加載并執行bootloader程序,CPU通過拷貝或映射bootloader程序到內存,然后執行bootloader的第一條指令。通過閱讀官方的uboot燒寫方法,發現A20通過uboot引導系統之前先載入了uboot SPL。什么是SPL?通過查閱uboot的官網資料得知,SPL是一個迷你版的uboot,全拼為Second Program Loader。適用于SOC的內部SRAM<64K的情況,用它來加載完整的uboot程序到SDRAM,并通過完整uboot加載內核來啟動系統。其中SRAM一般指CPU內部的L1/L2或外部的L2高速緩存,這里即為Boot ROM,而SDRAM一般指內存。

SPL程序流程如下:

  • 初始化ARM處理器
  • 初始化串口控制臺
  • 配置時鐘和最基礎的分頻
  • 初始化SDRAM
  • 配置引腳多路復用功能
  • 啟動設備初始化(即上面選擇的啟動設備)
  • 加載完整的uboot程序并轉交控制權
  • 啟動設備選擇程序的流程圖:?

    搞清楚了上面的概念,可以知道Cubieboard出廠已經燒寫了NandFlash中的程序,即在啟動時使用的是NandFlash。現在根據全志A20上述步驟,我們嘗試用SD Card0(即Cubieboard上卡槽中的TF卡)來啟動系統。

    環境準備

    本文所使用的主機環境為kubuntu 12.10,然而一般情況下,下面涉及到的命令對基于Debian的(X)ubuntu系列都應該適用。

    為不引起混淆,我們作如下約定:

    • 工作目錄為 $WORK_DIR
    • 命令均以root用戶執行

    筆者的設定如下:

    <span class="re2">WORK_DIR</span>=<span class="sy0">/</span>home<span class="sy0">/</span>itviewer<span class="sy0">/</span>src

    下載必須的工具軟件

    <span class="kw2">apt-get install</span> build-essential libncurses5-dev u-boot-tools qemu-user-static debootstrap <span class="kw2">git</span> binfmt-support libusb-<span class="nu0">1.0</span>-<span class="nu0">0</span>-dev pkg-config <span class="kw2">apt-get install</span> gcc-arm-linux-gnueabihf

    下載源碼

    從 github 下載 SPL,U-BOOT,Linux 內核源碼。注意 linux-sunxi 超過 3.8G ,耗時最長。如果您曾經下載過這些代碼,記得分別用 git pull 更新后再進行后續操作,因為代碼倉庫每天都有變化。

    <span class="kw3">cd</span> <span class="re1">$WORK_DIR</span> <span class="kw2">git clone</span> git:<span class="sy0">//</span>github.com<span class="sy0">/</span>linux-sunxi<span class="sy0">/</span>u-boot-sunxi.git <span class="kw2">git clone</span> git:<span class="sy0">//</span>github.com<span class="sy0">/</span>cubieboard2<span class="sy0">/</span>linux-sunxi <span class="kw2">git clone</span> git:<span class="sy0">//</span>github.com<span class="sy0">/</span>linux-sunxi<span class="sy0">/</span>sunxi-tools.git <span class="kw2">git clone</span> git:<span class="sy0">//</span>github.com<span class="sy0">/</span>linux-sunxi<span class="sy0">/</span>sunxi-boards.git

    編譯uboot

    <span class="kw3">cd</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>u-boot-sunxi<span class="kw2">make</span> distclean <span class="re2">CROSS_COMPILE</span>=arm-linux-gnueabihf-<span class="kw2">make</span> Cubieboard2 <span class="re2">CROSS_COMPILE</span>=arm-linux-gnueabihf-

    得到 u-boot-sunxi-with-spl.bin(同時生成的還有其它幾個文件,這里我們只用該文件,注意上面Cubieboard2,最新代碼需要首字母大寫)

    編譯kernel

    <span class="kw3">cd</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>linux-sunxi<span class="kw2">make</span> <span class="re2">ARCH</span>=arm <span class="re2">CROSS_COMPILE</span>=arm-linux-gnueabihf- cubieboard2_defconfig<span class="kw2">make</span> <span class="re2">ARCH</span>=arm <span class="re2">CROSS_COMPILE</span>=arm-linux-gnueabihf- <span class="re5">-j4</span> uImage modules

    得到內核文件 arch/arm/boot/uImage(還有其它內核模塊,這里暫時沒有用到)

    生成 boot.scr和script.bin

    在將uboot和kernel燒寫到TF卡之前,我們需要先編譯生成兩個啟動參數文件:boot.scr和script.bin。

    生成 boot.scr

    boot.scr是什么?

    根據資料描述(https://github.com/linux-sunxi/u-boot-sunxi/wiki#bootscr-support),u-boot在啟動的時候會在第一個分區(FAT/extX格式)尋找/boot.scr或者/boot/boot.scr文件,boot.scr中可以包含用于載入script.bin,kernel,initrd(可選)以及設置內核啟動參數的uboot命令。

    boot.scr如何生成?

    在$WORK_DIR目錄新建 boot.cmd 文件,添加以下內容:

    setenv bootargs console<span class="sy0">=</span>ttyS0<span class="sy0">,</span><span class="nu0">115200</span> noinitrd disp<span class="sy0">.</span>screen0_output_mode<span class="sy0">=</span>EDID<span class="sy0">:</span>1280x1024p60 init<span class="sy0">=/</span>init root<span class="sy0">=/</span>dev<span class="sy0">/</span>mmcblk0p2 rootfstype<span class="sy0">=</span>ext4 rootwait panic<span class="sy0">=</span><span class="nu0">10</span> $<span class="br0">{</span>extra<span class="br0">}</span> fatload mmc <span class="nu0">0</span> <span class="nu12">0x43000000</span> boot<span class="sy0">/</span>script<span class="sy0">.</span>bin fatload mmc <span class="nu0">0</span> <span class="nu12">0x48000000</span> boot<span class="sy0">/</span>uImage bootm <span class="nu12">0x48000000</span>

    詳細解釋:

    1.上述第一行設置uboot的bootargs啟動參數,格式為 參數=值,不同參數使用空格分開,其中

    • console=ttyS0,115200 含義為使用特定的串口ttyS0,波特率為 115200
    • noinitrd 含義為不使用ramdisk(內存磁盤)
    • init=/init 含義為內核啟起來后,進入系統中運行的第一個腳本
    • root=/dev/mmcblk0p2 含義為指定rootfs的位置為TF卡第二個分區
    • rootfstype=ext4 含義為根文件系統類型
    • rootwait 含義為等待設備/dev/mmcblk0p2就緒后才嘗試掛載rootfs
    • panic=10 傳遞內核參數,當遇到panic(內核嚴重錯誤)時等待10秒后重啟
    • screen0_output_mode 設置合適的屏幕顯示分辨率

    更多的參數可以通過查看Linux內核源碼目錄下Documentation/kernel-parameters.txt文件了解

    2.第二行和第三行為將script.bin和內核uImage加載到指定內存地址。fatload是U-Boot中裝載linux kernel 到內存的指令。

    基本用法:fatload <interface> <dev[:part]> <addr> <filename> <bytes>

    • interface:所用到接口,如:MMC、USB
    • dev [:part]: 文件存放的設備 如:ide 0:1
    • addr: 裝載到內存的開始地址。
    • filename: 裝載的文件名稱。
    • bytes: copy的字節數.

    3.第四行bootm 用于將內核映像加載到指定的地址

    保存文件后,執行以下命令生成boot.scr:

    mkimage <span class="sy0">-</span>C none <span class="sy0">-</span>A arm <span class="sy0">-</span>T script <span class="sy0">-</span>d boot<span class="sy0">.</span>cmd boot<span class="sy0">.</span>scr

    生成 script.bin

    script.bin是什么?

    script.bin是被全志SOC內核驅動或LiveSuit使用的針對特定目標板的二進制配置文件,包含如何設置基于A10/A20目標版的各種外設,端口,I/O針腳信息。

    其對應的可讀文本文件格式為FEX,可以利用 Sunxi-tools在二進制和文本文件之間進行轉換。更多關于FEX配置的信息可以參考http://linux-sunxi.org/Fex_Guide

    script.bin如何生成?

    首先需要編譯sunxi-tools:

    <span class="kw3">cd</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>sunxi-tools <span class="kw2">make</span>

    得到fex2bin、bin2fex等文件,其中fex2bin能把 *.fex 文件生成 *.bin文件。反之bin2fex可以將得到的*.bin文件生成可讀的*.fex文件。

    然后編譯生成script.bin:

    <span class="kw3">cd</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>sunxi-boards<span class="sy0">/</span>sys_config<span class="sy0">/</span>a20 <span class="re1">$WORK_DIR</span><span class="sy0">/</span>sunxi-tools<span class="sy0">/</span>fex2bin cubieboard2.fex script.bin

    燒寫uboot和kernel到TF卡

    上面羅嗦了這么多,其實就是為了將uboot和kernel燒寫到TF卡上并能夠啟動,OK,讓我們先從分區開始:

    A20 芯片上電啟動的時候,會讀取SD卡最前面的 1M 內容,從而得到 bootloader,所以我們需要把 u-boot 寫到SD卡的前1M區間。

    其中詳細的SD卡布局如下:

    起始大小用途
    08KB存放分區表等內容
    824KBSPL loader
    32512KBu-boot
    544128KBenvironment
    672352KB保留
    1024-用于剩余分區

    接下來,我們開始使用fdisk進行分區(由于sfdisk對部分TF不兼容,故除非你真的知道怎么用sfdisk,否則不要使用):

    將TF卡插到電腦上并確認設備名,為不至于混淆,我們使用sdX代替,您需要根據自己的情況修改,如sdb:

    <span class="re2">card</span>=<span class="sy0">/</span>dev<span class="sy0">/</span>sdX <span class="kw2">dd</span> <span class="re2">if</span>=<span class="sy0">/</span>dev<span class="sy0">/</span>zero <span class="re2">of</span>=<span class="co1">${card}</span> <span class="re2">bs</span>=1M <span class="re2">count</span>=<span class="nu0">1</span> <span class="co0"># 把SD卡前1M的區域填充為0,預留給 u-boot</span> sfdisk <span class="re5">-R</span> <span class="co1">${card}</span> <span class="co0"># 重新讀取${card}</span> <span class="kw2">fdisk</span> <span class="co1">${card}</span> <span class="co0">#使用fdisk進行分區</span>

    具體分區步驟如下:

    建立第一個分區

    root@kubuntu:~/src/u-boot-sunxi# fdisk ${card} Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel with disk identifier 0x911332e8. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable.Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)Command (m for help): n #鍵入n然后回車 Partition type:p primary (0 primary, 0 extended, 4 free)e extended Select (default p): #直接回車 Using default response p Partition number (1-4, default 1): #直接回車 Using default value 1 First sector (2048-15278079, default 2048): #直接回車 Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-15278079, default 15278079): +64M #鍵入+64M后回車,即分區大小為64M

    建立第二個分區

    Command (m for help): n #鍵入n然后回車 Partition type:p primary (1 primary, 0 extended, 3 free)e extended Select (default p): #直接回車 Using default response p Partition number (1-4, default 2): #直接回車 Using default value 2 First sector (133120-15278079, default 133120): #直接回車 Using default value 133120 Last sector, +sectors or +size{K,M,G} (133120-15278079, default 15278079): #直接回車,即第二個分區使用全部剩余空間 Using default value 15278079

    接下來指定分區類型:

    Command (m for help): t #鍵入t然后回車 Partition number (1-4): 1 #鍵入1然后回車,即指定第一個分區 Hex code (type L to list codes): c #鍵入c然后回車,即指定第一個分區為vfat Changed system type of partition 1 to c (W95 FAT32 (LBA))Command (m for help): w #鍵入w然后回車,保存分區表 The partition table has been altered!Calling ioctl() to re-read partition table. Syncing disks.

    格式化分區:

    mkfs.vfat <span class="co1">${card}</span><span class="nu0">1</span> mkfs.ext4 <span class="co1">${card}</span><span class="nu0">2</span> <span class="co0">#需要稍等片刻</span>

    然后寫入bootloader:

    <span class="kw3">cd</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>u-boot-sunxi <span class="kw2">dd</span> <span class="re2">if</span>=u-boot-sunxi-with-spl.bin <span class="re2">of</span>=<span class="re1">$card</span> <span class="re2">bs</span>=<span class="nu0">1024</span> <span class="re2">seek</span>=<span class="nu0">8</span>

    最后安裝內核 uImage,設置啟動參數:

    <span class="kw2">mount</span> <span class="co1">${card}</span><span class="nu0">1</span> <span class="sy0">/</span>mnt <span class="kw2">mkdir</span> <span class="sy0">/</span>mnt<span class="sy0">/</span>boot <span class="kw2">cp</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>linux-sunxi<span class="sy0">/</span>arch<span class="sy0">/</span>arm<span class="sy0">/</span>boot<span class="sy0">/</span>uImage <span class="sy0">/</span>mnt<span class="sy0">/</span>boot <span class="kw2">cp</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>sunxi-boards<span class="sy0">/</span>sys_config<span class="sy0">/</span>a20<span class="sy0">/</span>script.bin <span class="sy0">/</span>mnt<span class="sy0">/</span>boot <span class="kw2">cp</span> <span class="re1">$WORK_DIR</span><span class="sy0">/</span>boot.scr <span class="sy0">/</span>mnt<span class="sy0">/</span> <span class="kw2">sync</span> <span class="sy0">&&</span> <span class="kw2">umount</span> <span class="sy0">/</span>mnt

    至此,啟動到linux內核的工作已經完成,接下來我們就可以觀看linux內核啟動過程、進行內核調試了。

    打印串口調試信息

    通過查看串口輸出信息,可以方便我們判斷問題所在,進而找到解決問題的方法。

    在linux和windows下有多種串口調試工具可供使用,這里僅給出兩篇參考文章:

    • http://linux-sunxi.org/Cubieboard/TTL
    • http://cn.cubiebook.org/index.php?title=Cubieboard/串口調試

    這里附上筆者的串口輸出信息:http://mer.jolladev.net/data/media/cutecom.txt

    信息結尾由于無法掛載根文件系統、啟動init而等待10秒后重啟。

    總結

    本文參考了眾多網絡內容,在后面列出了主要文章地址,在此一并感謝。

    之所以寫這篇內容,是因為從本人入手cubieboard2以來,通過苦尋資料,在各種痛苦與錯誤的嘗試中不斷走上了”正道“,深知對于一個沒有嵌入式開發基礎或開發經驗的普通玩家而言,想把各種環節搞清楚是一件很難的事情,故通過大量引用、參考網絡內容加上自己的摸索,總結出該文,以期望對新的玩家能夠有所幫助;就嵌入式linux而言,整個 加電——啟動bootloader——啟動內核——加載rootfs流程對于新手會感到非常的模糊,而不知如何下手。本篇內容盡可能詳細的描述了利用cubieboard從加電到啟動linux內核的整個操作過程,為進一步學習如何構建一個可運行的linux系統打下了基礎。后面,將會在此基礎上繼續介紹如何進一步掛載跟文件系統,啟動到shell甚至GUI圖形界面,從而構建一個完整、可用的linux系統。

    參考

    • http://linux-sunxi.org/Bootable_SD_card
    • http://linux-sunxi.org/Boot
    • https://github.com/linux-sunxi/u-boot-sunxi/wiki
    • http://cn.cubieboard.org/forum.php?mod=viewthread&tid=1108&extra=page%3D1
    • http://blog.csdn.net/yichunjie/article/details/8661176
    • http://blog.csdn.net/abc47bca/article/details/6306005

    總結

    以上是生活随笔為你收集整理的Bootloader加载过程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产毛片高清 | 天天射综合| 91国产视频在线播放 | 久久精品视频日本 | 成人毛片网站 | 伊人网影院| 制服 丝袜 综合 日韩 欧美 | 色伊人影院 | av夜色 | 三级爱爱| 97视频免费在线观看 | 污网站在线免费 | 久草视频播放 | 久久在线一区二区 | 亚洲精选在线 | av网站一区| 91福利在线导航 | 亚洲视频91 | 天天婷婷 | 99精品小视频 | 亚洲成av人片在线观看 | 能免费看黄色的网站 | 亚洲一区二区三区四区电影 | 久热99| 久久av综合网 | 黄网在线免费看 | 男男gay动漫 | 中文字幕亚洲成人 | 蜜桃av网站 | 亚洲午夜电影网 | 久久精品在线 | www.婷婷色 | 亚洲视频一区在线观看 | 免费日韩一区二区 | 99久久精品无码一区二区毛片 | 久久艹av| 黄色亚洲精品 | 免费观看黄网站 | 成年人爱爱视频 | 日韩视频在线一区二区 | 日本在线不卡一区 | 亚洲av无码一区二区三区在线播放 | 成人亚洲一区二区 | 亚洲AV成人无码久久精品巨臀 | 中文人妻熟女乱又乱精品 | 999久久久精品视频 亚洲视频精品在线 | 九九亚洲视频 | 欧美一区二区三区视频在线观看 | 中文字幕av影院 | 国产成人精品无码高潮 | 亚洲一区二区三区在线 | 麻豆出品| 国产精品污污 | 自拍三级 | 欧美一区二区三区激情啪啪 | 久久久久一级 | 精品人妻一区二区三区免费看 | 偷啪自啪| 黄色三级图片 | 无遮挡aaaaa大片免费看 | 免费看91视频| 国产富婆一级全黄大片 | 自拍偷在线精品自拍偷无码专区 | 国产激情精品一区二区三区 | 老子午夜影院 | 久久精品丝袜高跟鞋 | 国产高清无密码一区二区三区 | 粉嫩av一区二区三区四区五区 | 成人午夜视频精品一区 | 国产黑丝视频 | 欧美一区二区三区影院 | 欧美黑人孕妇孕交 | av第下页 | 久久网一区二区 | 任你躁av一区二区三区 | 黄色1级毛片 | 亚洲中文无码久久 | 午夜一二三区 | www.youjizz.com日本 | 国产精彩视频一区二区 | 久久久久久人妻一区二区三区 | 色福利网| 狂野欧美性猛交xxⅹ李丽珍 | 国产又粗又硬视频 | 国产激情免费 | 欧美91av| 性感av在线 | 久久久久久久成人 | 欧美男同又粗又长又大 | 午夜剧场欧美 | 99热精品在线 | 欧美黄色a| 一区二区三区成人 | 欧美视频一区二区 | 女女互磨互喷水高潮les呻吟 | 尤物视频一区 | 少妇视频一区二区三区 | 国产精品久久久久999 | 老师张开让我了一夜av |