詳細分析make uboot 最後的編譯連結的具體執行過程
之前分析uboot都是從原始碼分析, 找到一篇好文是從uboot的make資訊來反向分析的.原文連結:
正常編譯uboot過程分兩步:1. make xxxx_config 生成配置檔案 2. make . 在make之後uboot.bin是如何生成的, 可以分析make的過程:
- UNDEF_SYM=`arm-linux-objdump -x board/ams/as3536/libas3536.a lib_generic/libgeneric.a lib_generic/lzma/liblzma.a cpu/arm926ejs/libarm926ejs.a cpu/arm926ejs/ams/libams.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/libyaffs2.a net/libnet.a disk/libdisk.a drivers/bios_emulator/libatibiosemu.a drivers/block/libblock.a drivers/dma/libdma.a drivers/fpga/libfpga.a drivers/gpio/libgpio.a drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a drivers/input/libinput.a drivers/misc/libmisc.a drivers/mmc/libmmc.a drivers/mtd/libmtd.a drivers/mtd/nand/libnand.a drivers/mtd/nand_legacy/libnand_legacy.a drivers/mtd/onenand/libonenand.a drivers/mtd/ubi/libubi.a drivers/mtd/spi/libspi_flash.a drivers/net/libnet.a drivers/net/phy/libphy.a drivers/net/sk98lin/libsk98lin.a drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a drivers/spi/libspi.a drivers/rtc/librtc.a drivers/serial/libserial.a drivers/usb/libusb.a drivers/video/libvideo.a common/libcommon.a libfdt/libfdt.a api/libapi.a post/libpost.a |
- sed -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'|sort|uniq`;
- cd /home/crifan/develop/uboot/uboot_as3536/u-boot-2009.03_toHome && arm-linux-ld -Bstatic -T /home/crifan/develop/uboot/uboot_as3536/u-boot-2009.03_toHome/board/ams/as3536/u-boot.lds -Ttext 0x00000000 $UNDEF_SYM cpu/arm926ejs/start.o
- --start-group lib_generic/libgeneric.a lib_generic/lzma/liblzma.a cpu/arm926ejs/libarm926ejs.a cpu/arm926ejs/ams/libams.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/libyaffs2.a net/libnet.a disk/libdisk.a drivers/bios_emulator/libatibiosemu.a drivers/block/libblock.a drivers/dma/libdma.a drivers/fpga/libfpga.a drivers/gpio/libgpio.a drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a drivers/input/libinput.a drivers/misc/libmisc.a drivers/mmc/libmmc.a drivers/mtd/libmtd.a drivers/mtd/nand/libnand.a drivers/mtd/nand_legacy/libnand_legacy.a drivers/mtd/onenand/libonenand.a drivers/mtd/ubi/libubi.a drivers/mtd/spi/libspi_flash.a drivers/net/libnet.a drivers/net/phy/libphy.a drivers/net/sk98lin/libsk98lin.a drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a drivers/spi/libspi.a drivers/rtc/librtc.a drivers/serial/libserial.a drivers/usb/libusb.a drivers/video/libvideo.a common/libcommon.a libfdt/libfdt.a api/libapi.a post/libpost.a board/ams/as3536/libas3536.a --end-group -L /home/crifan/develop/buildroot/buildroot-2009.11/output/staging/usr/bin/../lib/gcc/arm-linux-uclibcgnueabi/4.3.4 -lgcc
- -Map u-boot.map -o u-boot
- arm-linux-objcopy -O srec u-boot u-boot.srec
- arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
下面儘可能的具體分析:
一 第一條命令分析
- UNDEF_SYM=`arm-linux-objdump -x board/ams/as3536/libas3536.a lib_generic/libgeneric.a lib_generic/lzma/liblzma.a cpu/arm926ejs/libarm926ejs.a cpu/arm926ejs/ams/libams.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/libyaffs2.a net/libnet.a disk/libdisk.a drivers/bios_emulator/libatibiosemu.a drivers/block/libblock.a drivers/dma/libdma.a drivers/fpga/libfpga.a drivers/gpio/libgpio.a drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a drivers/input/libinput.a drivers/misc/libmisc.a drivers/mmc/libmmc.a drivers/mtd/libmtd.a drivers/mtd/nand/libnand.a drivers/mtd/nand_legacy/libnand_legacy.a drivers/mtd/onenand/libonenand.a drivers/mtd/ubi/libubi.a drivers/mtd/spi/libspi_flash.a drivers/net/libnet.a drivers/net/phy/libphy.a drivers/net/sk98lin/libsk98lin.a drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a drivers/spi/libspi.a drivers/rtc/librtc.a drivers/serial/libserial.a drivers/usb/libusb.a drivers/video/libvideo.a common/libcommon.a libfdt/libfdt.a api/libapi.a post/libpost.a |
- sed -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'|sort|uniq`;
1. UNDEF_SYM
UNDEF_SYM=XXX, 這表示將XXX賦值給UNDEF_SYM. 但是在這裡是 UNDEF_SYM=`XXX`, 這裡要做兩點說明
(1) 字元 ` 叫反引號, 就是數字1左邊那個按鍵, 這個 反引號 表示在shell中,用於要包含的命令, 如果不加 反引號則表示為普通的字串, 所以上邊表示將 arm-linux-objdump.... | sed -n -e ' s/.*(__uboot_cmd_.*)/-ul/p' | sort |unip 執行的結果賦值給UNDDEF_SYM
(2) 空格加上反斜槓, 表示連線符
2. objdump -x
先來看下objdump -x中 -x引數的含義: " -x, –all-headers Display the contents of all headers" 顯示(.a庫檔案)所包含全部的頭(資訊).
因此上面的就是把所有的.a庫檔案中的頭資訊都匯出來給那個變數. 而具體的headers是啥樣子的,我們可以以第一個庫libas3536.a為例,來看看結果: arm-linux-objdump -x board/ams/as3536/libas3536.a
由於結果太長,此處只節選部分顯示:
- In archive board/ams/as3536/libas3536.a:
- as3536.o: file format elf32-littlearm
- rw-r--r-- 1000/1000 5872 Feb 26 23:27 2010 as3536.o
- architecture: arm, flags 0x00000011:
- HAS_RELOC, HAS_SYMS
- start address 0x00000000
- private flags = 600: [APCS-32] [VFP float format] [software FP]
- Sections:
- Idx Name Size VMA LMA File off Algn
- 0 .text 000001c8 00000000 00000000 00000034 2**2
- CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
- 1 .data 00000000 00000000 00000000 000001fc 2**0
- CONTENTS, ALLOC, LOAD, DATA
- 2 .bss 00000000 00000000 00000000 000001fc 2**0
- ALLOC
- 3 .debug_abbrev 00000155 00000000 00000000 000001fc 2**0
- CONTENTS, READONLY, DEBUGGING
- 4 .debug_info 000002b7 00000000 00000000 00000351 2**0
- CONTENTS, RELOC, READONLY, DEBUGGING
- 5 .debug_line 00000127 00000000 00000000 00000608 2**0
- CONTENTS, RELOC, READONLY, DEBUGGING
- 6 .rodata.str1.1 00000011 00000000 00000000 0000072f 2**0
- CONTENTS, ALLOC, LOAD, READONLY, DATA
- 7 .rodata 0000000a 00000000 00000000 00000740 2**0
- CONTENTS, ALLOC, LOAD, READONLY, DATA
- .............
- SYMBOL TABLE:
- 00000000 l df *ABS* 00000000 as3536.c
- 00000000 l d .text 00000000 .text
- 00000000 l d .data 00000000 .data
- 00000000 l d .bss 00000000 .bss
- 00000000 l d .debug_abbrev 00000000 .debug_abbrev
- 00000000 l d .debug_info 00000000 .debug_info
- 00000000 l d .debug_line 00000000 .debug_line
- 00000000 l d .rodata.str1.1 00000000 .rodata.str1.1
- 00000000 l O .rodata 0000000a __FUNCTION__.2915
- 00000000 l d .rodata 00000000 .rodata
- ................
- 00000000 *UND* 00000000 i2cIsMasterBusy
- 00000000 *UND* 00000000 gpioInitialise
- 00000000 *UND* 00000000 uartInitialize
- 00000000 *UND* 00000000 serial_init
- 00000000 *UND* 00000000 mpmcInitialize
- 00000000 *UND* 00000000 mpmcDynamicConfig
- 00000000 *UND* 00000000 icache_enable
- 00000000 *UND* 00000000 dcache_enable
- ...............
- as353x_nand.o: file format elf32-littlearm
- rw-r--r-- 1000/1000 24080 Feb 26 23:27 2010 as353x_nand.o
- architecture: arm, flags 0x00000011:
- HAS_RELOC, HAS_SYMS
- start address 0x00000000
- private flags = 600: [APCS-32] [VFP float format] [software FP]
- Sections:
- Idx Name Size VMA LMA File off Algn
- 0 .text 00000df8 00000000 00000000 00000034 2**2
- CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
- 1 .data 00000000 00000000 00000000 00000e2c 2**0
- CONTENTS, ALLOC, LOAD, DATA
- 2 .bss 00000000 00000000 00000000 00000e2c 2**0
- ALLOC
- 3 .debug_abbrev 00000286 00000000 00000000 00000e2c 2**0
- CONTENTS, READONLY, DEBUGGING
- ...............
- 6 .rodata.str1.1 00000093 00000000 00000000 00002aab 2**0
- CONTENTS, ALLOC, LOAD, READONLY, DATA
- 7 .rodata 00000185 00000000 00000000 00002b3e 2**0
- CONTENTS, ALLOC, LOAD, READONLY, DATA
- ...................
- SYMBOL TABLE:
- 00000000 l df *ABS* 00000000 as353x_nand.c
- 00000000 l d .text 00000000 .text
- 00000000 l d .data 00000000 .data
- ..........................
- 00000ce4 l F .text 00000114 as353x_nand_read_buf_swbch4
- 00000bd0 l F .text 00000114 as353x_nand_write_buf_swbch4
- 00000a28 l F .text 000001a8 as353x_enable_hwecc_swbch4
- 00000a0c l F .text 0000001c as353x_calculate_ecc
- 00000944 l F .text 000000c8 as353x_correct_data
- 00000460 l F .text 00000034 as353x_nand_ready
- .................
- 00000043 l O .rodata 00000017 __FUNCTION__.3286
- 0000005a l O .rodata 00000013 __FUNCTION__.3214
- .......................
- 00000000 *UND* 00000000 bchDecode
- 00000000 *UND* 00000000 bchEncodeT4
- 00000000 *UND* 00000000 DebugClrRegBits8
- 00000000 *UND* 00000000 DebugRReg32
- .............
(1). 上面的SYMBOL_TABLE中類似於:
- 00000a0c l F .text 0000001c as353x_calculate_ecc
- 00000944 l F .text 000000c8 as353x_correct_data
- 00000460 l F .text 00000034 as353x_nand_ready
(2). 上面SYMBOL_TABLE中類似於:
- 00000000 *UND* 00000000 udelay
- 00000000 *UND* 00000000 bchDecode
- 00000000 *UND* 00000000 bchEncodeT4
(3). 類似於
- as353x_nand.o: file format elf32-littlearm
- rw-r--r-- 1000/1000 24080 Feb 26 23:27 2010 as353x_nand.o
- architecture: arm, flags 0x00000011:
- HAS_RELOC, HAS_SYMS
綜上所述, 每個 .a 檔案中都包含了若干個 .o 檔案, 而每個 .o 檔案都對應一個 .c 或者一個 .S 檔案
3. sed命令
(1) | 表示將前邊objdump命令生成的內容通過管道送給後邊的 sed 命令去處理
- sed -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'
-n, –quiet, –silent, 取消自動列印模式空間
(3) sed 預設會列印匹配的每一行,但是可以使用-n選項將其關閉。在這種情況下,只有用P命令顯式說明的行才出現在輸出中。如
sed –n ‘ / 模式 /p ’
sed –n ‘ / 模式 /!p ’
所以,-n的意思就是,預設後面如果有匹配的內容,比如要替換字元子類的,就會列印這些相關資訊,此處加了-n,就no print了.
(4) -e 指令碼, –expression=指令碼, 新增“指令碼”到程式的執行列表, 簡單的來說,就是把-e後面跟的內容,當做要執行的指令碼(命令)放入到命令列表中(以待後面分別執行這些命令去處理字元流/串),具體用法例子所示:
- >cat file
- I have three dogs and two cats
- >sed -e ‘s/dog/cat/g’ -e ‘s/cat/elephant/g’ file
- I have three elephants and two elephants
- 上面的例子中,sed,對於字元流:
- I have three dogs and two cats
- 會先用第一個-e後面的’s/dog/cat/g’,即所謂的腳步或者叫做命令,來處理。
- 具體處理結果就是,g代表全域性範圍,s/dog/cat代表把字串dog替換為cat,所以處理後,元字元流就變成:
- I have three cats and two cats
- 然後對於處理後的這個字元流,繼續用後面的’s/cat/elephant/g’來處理,即將其中的cat都替換為elephant,所以處理後的結果為:
- I have three elephants and two elephants
- sed -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'
- s/.*(__u_boot_cmd_.*)/-u1/p
第一部分 :s,表示substitue,字