Cubietruck---8. u-boot及boot.img簡略分析
1. lichee下編譯命令
[email protected]:/work/ct/lichee$ ./build.sh -p sun7i_android -m uboot
u-boot的編譯是用指令碼lichee/u-boot/build.sh
-
function build_uboot()
-
{
-
make distclean CROSS_COMPILE=arm-linux-gnueabi-
-
make -j8 ${LICHEE_CHIP} CROSS_COMPILE=arm-linux-gnueabi-
-
[ $? -ne 0 ] &&
-
cp -f u-boot.bin ../out/${LICHEE_PLATFORM}/common/
- }
- cd /work/ct/lichee/u-boot && arm-linux-gnueabi-ld -pie -T u-boot.lds -Bstatic -Ttext 0x4A000000 *.o -o u-boot
-
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-
OUTPUT_ARCH(
-
ENTRY(_start)
-
SECTIONS
-
{
-
. = 0x00000000; //在連結時通過-Ttext改為0x4A000000
-
. = ALIGN(4);
-
.text :
-
{
-
arch/arm/cpu/armv7/start.o (.text) //u-boot的開始
-
*(.text)
- }
-
}
二. u-boot分析
1. stars.S
在arch/arm/cpu/armv7/start.S中,這兒的start.S就非常簡單了,因為執行地址與載入地址相同,所以程式碼不需要再拷貝到另外的地方去,
並且在此之前ram與cpu的頻率都配好了,所以這兒在中斷向量之後,稍做配置就進入了c程式碼的board_init_f
2. 啟動linux
在arch/arm/lib/board.c中
好像這兒挺複雜的先進入board_init_f --> relocate_code --> start.S--> board_init_r
board_init_r中有main_loop--> run_command
啟動核心的命令是:
bootcmd=run setargs_nand boot_normal
展開後就是:
run setenv bootargs console=ttyS0,115200 root=/dev/nandd
run sunxi_flash read 40007800 boot;boota 40007800
為什麼這兒是40007800呢, 因為核心要執行在0x40008000處,而boot.img中前0x800(2048)位元組是header(大小為0x800),
header之後是核心,所以將boot.img讀到0x40007800,前0x800是header,那麼核心就正好放在了0x40008000處.
boota 40007800
-
int do_boota (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-
{
-
addr = simple_strtoul(argv[1], NULL, 16); //將字串0x40007800存在addr中
-
//這個fastboot_boot_img_hdr結構體與 pc上的mkbootimg的結構體是一個,只不過名字變了
-
struct fastboot_boot_img_hdr *fb_hdr = (struct fastboot_boot_img_hdr *)addr;
-
//hdr指向核心在記憶體的起始地址
-
image_header_t *hdr =(image_header_t *)(addr + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE);
-
//將boot.img的header備份一下
-
memcpy(boot_hdr, (void*) addr, sizeof(*hdr));
-
if (memcmp(fb_hdr->magic, FASTBOOT_BOOT_MAGIC, 8)) { //檢驗
-
puts("boota: bad boot image magic, maybe not a boot.img?\n");
-
return 1;
-
}
-
kaddr = addr + fb_hdr->page_size;
-
raddr = kaddr + ALIGN(fb_hdr->kernel_size, fb_hdr->page_size);
-
if((fb_hdr->unused[0] == 0x55) &&(fb_hdr->unused[1] == 0xaa))
-
{
-
dbmsg("bootimg load in boot1!\n");
-
do_boota_linux(fb_hdr); //1.1核心的啟動
-
tick_printf(__FILE__, __LINE__);
-
}
-
puts("Boot linux failed, control return to monitor\n");
-
return 0;
- }
在arch/arm/lib/bootm.c中,傳遞initram的起始地址
-
int do_boota_linux (struct fastboot_boot_img_hdr *hdr)
-
{
-
ulong initrd_start, initrd_end;
-
void (*kernel_entry)(int zero, int arch, uint
params);
-
bd_t *bd = gd->bd;
-
kernel_entry = (void (*)(int, int, uint))(hdr->kernel_addr); //將地址0x40008000轉為函式
-
initrd_start = hdr->ramdisk_addr;
-
initrd_end = initrd_start + hdr->ramdisk_size;
-
setup_start_tag (bd); //配置tag結構體開始
- //設定tag
-
....
-
setup_initrd_tag (bd, initrd_start, initrd_end); //配置initram,將起始地址與大小傳給tag
-
setup_end_tag (bd); //配置tag結構體結束
-
sunxi_flash_exit();
-
announce_and_cleanup(); //引導核心前的初始,清tlb類似
-
*(volatile unsigned int *)(0x01c20C00 + 0x84 ) = 0;
-
*(volatile unsigned int *)(0x01c20C00 + 0x8C ) = 0x05DB05DB;
-
*(volatile unsigned int *)(0x01c20C00 + 0x80 ) = 0;
-
*(volatile unsigned int *)(0x01c20000 + 0x144) &= ~(1U << 31);
-
kernel_entry(0, bd->bi_arch_number, bd->bi_boot_params); //跳到0x40008000處執行
-
return 1;
- }
3.1 boot.im生成過程
./android42/out/host/linux-x86/bin/mkbootimg --kernel ./linux-3.3/bImage --ramdisk ./android42/out/target/product/sugar-cubietruck/ramdisk.img --base 0x40000000 --output./android42/out/target/product/sugar-cubietruck/boot.img
mkbootimg有四個引數:
kernel 指定bImage的路徑
ramdisk 指定ramdisk的路徑
base 指定kerenel與ramdisk的基地址,為0x40000000
output 指定輸出檔案的路徑
在android42/system/core/mkbootimg/mkbootimag.c中
-
int main(int argc, char **argv)
-
{
-
boot_img_hdr hdr;
-
unsigned base = 0x10000000; //由引數base確定0x40000000
-
unsigned kernel_offset = 0x00008000;
-
unsigned ramdisk_offset = 0x01000000;
-
unsigned second_offset = 0x00f00000;
-
unsigned tags_offset = 0x00000100;
-
hdr.page_size = pagesize;
-
hdr.kernel_addr = base + kernel_offset; //0x40008000
-
hdr.ramdisk_addr = base + ramdisk_offset; //0x41000000
-
hdr.second_addr = base + second_offset; //0x40f00000
-
hdr.tags_addr = base + tags_offset; //0x40000100
-
kernel_data = load_file(kernel_fn, &hdr.kernel_size); //將核心讀取到buffer中(函式中有malloc)
-
ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); //將ramdisk讀取到buffer中(函式中有malloc)
- memcpy(hdr.id, sha, SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE);
-
fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); //開啟輸出檔案boot.img
-
write(fd, &hdr, sizeof(hdr)); //將head寫入到boot.img中
-
write_padding(fd, pagesize, sizeof(hdr)); //2048(0x800)位元組對齊
-
write(fd, kernel_data, hdr.kernel_size); //將kernel寫入到boot.img中
-
write_padding(fd, pagesize, hdr.kernel_size); //2048(0x800)位元組對齊
-
write(fd, ramdisk_data, hdr.ramdisk_size); //將ramdisk寫入到boot.img中
-
write_padding(fd, pagesize, hdr.ramdisk_size); //2048(0x800)位元組對齊
-
return 0;
- }
所以這個boot.img是由3部分組成
header (kernel_size代表了核心的大小,kernel_addr)
kernel
ramdisk
-
struct fastboot_boot_img_hdr {
-
unsigned char magic[FASTBOOT_BOOT_MAGIC_SIZE];
-
unsigned kernel_size; //核心的大小
-
unsigned kernel_addr; //核心的載入地址
-
unsigned ramdisk_size; //ramdisk的大小
-
unsigned ramdisk_addr; //ramdisk的起始地址
-
unsigned second_size; //其它
-
unsigned second_addr; //其它
-
unsigned tags_addr; //其它
-
unsigned page_size; //對齊到多少位元組
-
unsigned unused[2]; //
-
unsigned char name[FASTBOOT_BOOT_NAME_SIZE]; /* asciiz
product name */
-
unsigned char cmdline[FASTBOOT_BOOT_ARGS_SIZE];
-
unsigned id[8]; /* timestamp / checksum / sha1 / etc */
- };
相關推薦
Cubietruck---8. u-boot及boot.img簡略分析
一. u-boot的編譯與連結1. lichee下編譯命令[email protected]:/work/ct/lichee$ ./build.sh -p sun7i_android -m ubootu-boot的編譯是用指令碼lichee/u-boot/bui
移植u-boot-2011.03到S3C2440(utu2440)的方法與步驟###8. u-boot引導啟動nand flash中核心和根檔案系統cramfs和使用者檔案系統yaffs2支援
rivers/rtc/hctosys.c: unable to open rtc device (rtc0)uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2,
修復/boot及/etc/fstab、自制linux、編譯安裝內核
修復/boot、/etc/fstab、自制linux、編譯內核 修復/boot及/etc/fstab、自制linux、編譯安裝內核實驗一、破壞dev/sda 的MBR的446字節:破壞:dd if=/dev/zero of=/dev/sda bs=1 count=446 查看:hexdump -C -n
u-boot sdfuse命令燒錄分析----從SD卡載入核心
在u-boot移植過程中,由於u-boot燒錄在SD卡中,因此老是載入核心失敗,是什麼原因呢?在載入核心的列印資訊中有這樣類似的資訊: reading kernel.. 1120, 10240 MMC read: dev # 1, block # 112
u-boot啟動之Makefile結構分析
先進行配置命令: make smdk2410_config 在Makefile檔案中: smdk2410_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24
U-boot根目錄下的mkconfig分析
原文地址:http://blog.csdn.net/qq_28992301/article/details/51812103 U-boot根目錄下的mkconfig分析 此檔案位於uboot原始碼的根目錄下,是原始碼自帶的shell指令碼檔案,主要功能是建立符號連結以及一些標
boot.img的分析
3 boot.img的載入 在lk 中, smem_ptable_init 函式中會初始化 smem_apps_flash_start ,它通過讀share memory ,也就是ARM9端傳入的0:APPS 這樣在targe_init函式中,會將offset = smem_apps_flash_st
【imx6ul】U-Boot 2016.03執行過程分析-ARM Cortex-A7
uboot組織架構正在朝著linux架構方向發展,不同版本稍有不同,一下以U-Boot 2016.03為例。分析入口:以u-boot.lds(其決定了各個段的排布方式)開始:1、u-boot.lds://設定輸出檔案大小端格式 OUTPUT_FORMAT("elf32-lit
U-boot初始化階段流程分析
U-boot的初始化主要分為兩個階段 第一階段:主要是SOC內部的初始化,板級的初始化比較少,所以移植的修改量比較小。此階段由組合語言編寫,程式碼主體分佈在start.S和lowlevel_init.S中。 其中start.S作為主幹,其主要流程為: 注:
DAY-8 Linux基礎及常用命令(4)
打開 ip地址 grep 軟件包 linux基礎 tro mks 官網 vim 一、制作swap分區(命令) swapon –s 查看當前激活狀態的swap分區 free –m 以m為單位查看分區 swapoff關閉分區 swapon打開分區 添加swap分區——mks
Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage failed: Unable to find main class
spl final package exce main project clas ini exit 異常 [INFO] --- spring-boot-maven-plugin:1.5.6.RELEASE:repackage (default) @ spring-boot
12.8 Linux發展及VMware創建CentOS虛擬機
菜鳥驛站12.8Linux發展及VMware創建CentOS虛擬機內容:1. Linux發展 人物和事件2. Linux發行版本3. 通過VMware 搭建CentOs 系統4. 通過xshell連接5. 無法連接服務器排錯6. 雲服務器的簡單原理l Centos下載地址http://mirrors.aliy
Failure to transfer org.springframework.boot:spring-boot-maven-plugin
com info framework failure image 技術 找不到 update pen springboot 錯誤 Failure to transfer org.springframework.boot:spring-boot-maven-plugin
spring boot 2.0 源碼分析(五)
pen div shutdown down etc messages servle started fec 在上一篇文章中我們詳細分析了spring boot是如何準備上下文環境的,今天我們來看一下run函數剩余的內容。還是先把run函數貼出來: /**
CentOS6.8 安裝FTP及添加用戶
bool list 速度 from img 分享圖片 down log_file tp服務器 一 安裝FTP 1 檢測是否已經安裝FTP rpm -qa | grep vsftpd 2 若沒有,則進行安裝 yum install vsftpd 二 設置vsftpd開
java 7/ 8 中 HashMap 及 concurrentHashMap
前言: HashMap 不支援併發操作,而concurrentHashMap 支援併發操作,本文簡單介紹Java 7 、Java8 中HashMap 及 concurrentHashMap 底層實現。 1、Java 7 中 HashMap
c# UTF-8解碼編碼及陣列與List<string>之間轉換等基本知識點總結
Encoding utf8 = Encoding.UTF8; //首先用utf-8進行解碼 &
logstash 資料採集時間差8小時問題及解決
最近採用logstash採集日誌按天產生檔案 使用過程中發現logstash timestamp記錄的時間戳為UTC時間。 比我們的時區早8個小時。 不能確保每天的資料在同一檔案。 造成傳送到es裡的資料每天早上8點才建立索引,傳送的file的資料每天早上8點自動切割。 不符合我
Java 8 Stream介紹及使用
fin integer locate linked 包含 println swa character edi (原) stream的內容比較多,先簡單看一下它的說明: A sequence of elements supporting sequential and
centos下Jdk1.8的安裝及配置
安裝之前,首先要確定centos是否集成了自帶的openjdk,如果有,我們先要刪除自帶的openjdk,具體步驟如下: 1)在系統終端輸入:rpm -qa|grep java,如果有openjdk的話,會出現類似於XXXX_openjdk_XXX的資訊; 2)