u-boot這個東西從自我N年前使用到現在,變化好多,今天開始重新研究下,本系列的研究都是基於BeagleBoneBlack(bbb)開發板和 u-boot v201801版本的。
SPL介紹
在源代碼中 doc/README.SPL 中說得比較明白,我這里再歸納下。
現在很多處理器都內置一個BOOT ROM,執行部分初始化,並可從各種外設和存儲器中加載程序並執行,BOOT ROM中固化的程序被稱為一級程序加載器,被它加載的程序就稱為二級程序加載器(secondary program loader,即SPL)。其實u-boot本身就可以作為二級程序加載器,但不幸的是一般BOOT ROM之后,主存儲器都是沒有初始化的,例如BBB只有109K的內置RAM可用,這就限制了程序的大小,全功能的u-boot不能運行在這么小的RAM上運行。於是精簡的u-boot,u-boot-spl就此問世。
SPL精簡代碼的方式
在 Kconfig 文件中有一個 CONFIG_SPL 的選項,使能后,就會定義 CONFIG_SPL_BUILD
Makefile層面使用 CONFIG_SPL_BUILD 選擇不同的文件或文件夾進行編譯,例如
ifeq ($(CONFIG_SPL_BUILD),y) obj-y += board_spl.o else obj-y += board.o endif obj-$(CONFIG_SPL_BUILD) += foo.o
而C代碼層面,則使用 CONFIG_SPL_BUILD 宏來進行條件編譯,例如
#ifdef CONFIG_SPL_BUILD foo(); #endif
因為C代碼中有條件編譯選項,所以SPL和主u-boot代碼,不能復用.o文件,所有文件必須全部重新編譯。下面我們就來編譯試試看(arm-linux-gnueabihf-gcc請到linaro官方網站下載,然后放到PATH中即可)
make distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=bbb-build am335x_boneblack_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=bbb-build
為了說明下問題,我把打印的輸出放到這里
1 CHK include/config/uboot.release 2 Using .. as source for U-Boot 3 GEN ./Makefile 4 CHK include/generated/version_autogenerated.h 5 CHK include/generated/timestamp_autogenerated.h 6 UPD include/generated/timestamp_autogenerated.h 7 HOSTCC scripts/basic/fixdep 8 CC lib/asm-offsets.s 9 CHK include/generated/generic-asm-offsets.h 10 CC arch/arm/lib/asm-offsets.s 11 CHK include/generated/asm-offsets.h 12 HOSTCC tools/gen_eth_addr 13 HOSTCC tools/gen_ethaddr_crc.o 14 WRAP tools/lib/crc8.c 15 HOSTCC tools/lib/crc8.o 16 HOSTLD tools/gen_ethaddr_crc 17 HOSTCC tools/img2srec 18 HOSTCC tools/mkenvimage.o 19 HOSTCC tools/os_support.o 20 WRAP tools/lib/crc32.c 21 HOSTCC tools/lib/crc32.o 22 HOSTLD tools/mkenvimage 23 HOSTCC tools/aisimage.o 24 HOSTCC tools/atmelimage.o 25 WRAP tools/common/bootm.c 26 HOSTCC tools/common/bootm.o 27 HOSTCC tools/default_image.o 28 WRAP tools/lib/fdtdec_common.c 29 HOSTCC tools/lib/fdtdec_common.o 30 WRAP tools/lib/fdtdec.c 31 HOSTCC tools/lib/fdtdec.o 32 HOSTCC tools/fit_common.o 33 HOSTCC tools/fit_image.o 34 WRAP tools/common/image-fit.c 35 HOSTCC tools/common/image-fit.o 36 HOSTCC tools/image-host.o 37 WRAP tools/common/image.c 38 HOSTCC tools/common/image.o 39 HOSTCC tools/imagetool.o 40 HOSTCC tools/imximage.o 41 HOSTCC tools/kwbimage.o 42 WRAP tools/lib/md5.c 43 HOSTCC tools/lib/md5.o 44 HOSTCC tools/lpc32xximage.o 45 HOSTCC tools/mxsimage.o 46 HOSTCC tools/omapimage.o 47 HOSTCC tools/pblimage.o 48 HOSTCC tools/pbl_crc32.o 49 HOSTCC tools/vybridimage.o 50 WRAP tools/lib/rc4.c 51 HOSTCC tools/lib/rc4.o 52 HOSTCC tools/rkcommon.o 53 HOSTCC tools/rkimage.o 54 HOSTCC tools/rksd.o 55 HOSTCC tools/rkspi.o 56 HOSTCC tools/socfpgaimage.o 57 WRAP tools/lib/sha1.c 58 HOSTCC tools/lib/sha1.o 59 WRAP tools/lib/sha256.c 60 HOSTCC tools/lib/sha256.o 61 WRAP tools/common/hash.c 62 HOSTCC tools/common/hash.o 63 HOSTCC tools/ublimage.o 64 HOSTCC tools/zynqimage.o 65 HOSTCC tools/zynqmpimage.o 66 HOSTCC tools/libfdt/fdt.o 67 HOSTCC tools/libfdt/fdt_wip.o 68 HOSTCC tools/libfdt/fdt_sw.o 69 HOSTCC tools/libfdt/fdt_strerror.o 70 HOSTCC tools/libfdt/fdt_empty_tree.o 71 HOSTCC tools/libfdt/fdt_addresses.o 72 HOSTCC tools/libfdt/fdt_overlay.o 73 WRAP tools/lib/libfdt/fdt_ro.c 74 HOSTCC tools/lib/libfdt/fdt_ro.o 75 WRAP tools/lib/libfdt/fdt_rw.c 76 HOSTCC tools/lib/libfdt/fdt_rw.o 77 WRAP tools/lib/libfdt/fdt_region.c 78 HOSTCC tools/lib/libfdt/fdt_region.o 79 HOSTCC tools/gpimage.o 80 HOSTCC tools/gpimage-common.o 81 HOSTCC tools/dumpimage.o 82 HOSTLD tools/dumpimage 83 HOSTCC tools/mkimage.o 84 HOSTLD tools/mkimage 85 HOSTCC tools/proftool 86 HOSTCC tools/fdtgrep.o 87 HOSTLD tools/fdtgrep 88 LD arch/arm/cpu/built-in.o 89 CC arch/arm/cpu/armv7/cache_v7.o 90 AS arch/arm/cpu/armv7/cache_v7_asm.o 91 CC arch/arm/cpu/armv7/cpu.o 92 CC arch/arm/cpu/armv7/cp15.o 93 CC arch/arm/cpu/armv7/syslib.o 94 LD arch/arm/cpu/armv7/built-in.o 95 AS arch/arm/cpu/armv7/start.o 96 AS arch/arm/lib/vectors.o 97 AS arch/arm/lib/crt0.o 98 AS arch/arm/lib/setjmp.o 99 AS arch/arm/lib/relocate.o 100 CC arch/arm/lib/bootm-fdt.o 101 CC arch/arm/lib/bootm.o 102 CC arch/arm/lib/zimage.o 103 AS arch/arm/lib/memset.o 104 AS arch/arm/lib/memcpy.o 105 CC arch/arm/lib/sections.o 106 CC arch/arm/lib/stack.o 107 CC arch/arm/lib/interrupts.o 108 CC arch/arm/lib/reset.o 109 CC arch/arm/lib/cache.o 110 CC arch/arm/lib/cache-cp15.o 111 CC arch/arm/lib/psci-dt.o 112 LD arch/arm/lib/built-in.o 113 AS arch/arm/lib/ashldi3.o 114 AS arch/arm/lib/ashrdi3.o 115 CC arch/arm/lib/div0.o 116 AS arch/arm/lib/div64.o 117 AS arch/arm/lib/lib1funcs.o 118 AS arch/arm/lib/lshrdi3.o 119 AS arch/arm/lib/muldi3.o 120 AS arch/arm/lib/uldivmod.o 121 AR arch/arm/lib/lib.a 122 CC arch/arm/lib/eabi_compat.o 123 AS arch/arm/lib/crt0_arm_efi.o 124 CC arch/arm/lib/reloc_arm_efi.o 125 CC arch/arm/mach-omap2/am33xx/clock_am33xx.o 126 CC arch/arm/mach-omap2/am33xx/clock.o 127 CC arch/arm/mach-omap2/am33xx/sys_info.o 128 CC arch/arm/mach-omap2/am33xx/ddr.o 129 CC arch/arm/mach-omap2/am33xx/board.o 130 CC arch/arm/mach-omap2/am33xx/mux.o 131 CC arch/arm/mach-omap2/am33xx/prcm-regs.o 132 CC arch/arm/mach-omap2/am33xx/hw_data.o 133 CC arch/arm/mach-omap2/am33xx/fdt.o 134 CC arch/arm/mach-omap2/am33xx/clk_synthesizer.o 135 LD arch/arm/mach-omap2/am33xx/built-in.o 136 CC arch/arm/mach-omap2/reset.o 137 CC arch/arm/mach-omap2/timer.o 138 CC arch/arm/mach-omap2/utils.o 139 CC arch/arm/mach-omap2/sysinfo-common.o 140 CC arch/arm/mach-omap2/omap-cache.o 141 CC arch/arm/mach-omap2/boot-common.o 142 AS arch/arm/mach-omap2/lowlevel_init.o 143 CC arch/arm/mach-omap2/mem-common.o 144 CC arch/arm/mach-omap2/fdt-common.o 145 LD arch/arm/mach-omap2/built-in.o 146 CC board/ti/am335x/board.o 147 LD board/ti/am335x/built-in.o 148 CC board/ti/common/board_detect.o 149 LD board/ti/common/built-in.o 150 CC cmd/boot.o 151 CC cmd/bootm.o 152 CC cmd/help.o 153 CC cmd/version.o 154 CC cmd/blk_common.o 155 CC cmd/source.o 156 CC cmd/bdinfo.o 157 CC cmd/bootefi.o 158 CC cmd/bootz.o 159 CC cmd/console.o 160 CC cmd/echo.o 161 CC cmd/eeprom.o 162 CC cmd/elf.o 163 CC cmd/exit.o 164 CC cmd/ext4.o 165 CC cmd/ext2.o 166 CC cmd/fat.o 167 CC cmd/fdt.o 168 CC cmd/fs.o 169 CC cmd/gpio.o 170 CC cmd/i2c.o 171 CC cmd/itest.o 172 CC cmd/load.o 173 CC cmd/mem.o 174 CC cmd/mii.o 175 CC cmd/mdio.o 176 CC cmd/misc.o 177 CC cmd/mmc.o 178 CC cmd/net.o 179 CC cmd/part.o 180 CC cmd/pcmcia.o 181 CC cmd/pxe.o 182 CC cmd/sf.o 183 CC cmd/spi.o 184 CC cmd/time.o 185 CC cmd/test.o 186 CC cmd/usb.o 187 CC cmd/disk.o 188 CC cmd/fastboot.o 189 CC cmd/ximg.o 190 CC cmd/spl.o 191 CC cmd/dfu.o 192 CC cmd/gpt.o 193 CC cmd/nvedit.o 194 LD cmd/built-in.o 195 CC common/init/board_init.o 196 LD common/init/built-in.o 197 CC common/main.o 198 CC common/exports.o 199 CC common/hash.o 200 CC common/cli_hush.o 201 CC common/autoboot.o 202 CC common/board_f.o 203 CC common/board_r.o 204 CC common/board_info.o 205 CC common/bootm.o 206 CC common/bootm_os.o 207 CC common/fdt_support.o 208 CC common/miiphyutil.o 209 CC common/usb.o 210 CC common/usb_hub.o 211 CC common/usb_storage.o 212 CC common/splash.o 213 CC common/menu.o 214 CC common/update.o 215 CC common/cli_readline.o 216 CC common/cli_simple.o 217 CC common/console.o 218 CC common/dlmalloc.o 219 CC common/malloc_simple.o 220 CC common/image.o 221 CC common/image-android.o 222 CC common/image-fdt.o 223 CC common/image-fit.o 224 CC common/memsize.o 225 CC common/stdio.o 226 CC common/cli.o 227 CC common/dfu.o 228 CC common/command.o 229 CC common/s_record.o 230 CC common/xyzModem.o 231 LD common/built-in.o 232 CC disk/part.o 233 CC disk/part_dos.o 234 CC disk/part_iso.o 235 CC disk/part_efi.o 236 LD disk/built-in.o 237 LD drivers/adc/built-in.o 238 LD drivers/ata/built-in.o 239 CC drivers/block/blk_legacy.o 240 LD drivers/block/built-in.o 241 CC drivers/bootcount/bootcount.o 242 CC drivers/bootcount/bootcount_davinci.o 243 LD drivers/bootcount/built-in.o 244 CC drivers/core/device.o 245 CC drivers/core/fdtaddr.o 246 CC drivers/core/lists.o 247 CC drivers/core/root.o 248 CC drivers/core/uclass.o 249 CC drivers/core/util.o 250 CC drivers/core/device-remove.o 251 CC drivers/core/dump.o 252 LD drivers/core/built-in.o 253 CC drivers/crypto/fsl/sec.o 254 LD drivers/crypto/fsl/built-in.o 255 LD drivers/crypto/rsa_mod_exp/built-in.o 256 LD drivers/crypto/built-in.o 257 CC drivers/dfu/dfu.o 258 CC drivers/dfu/dfu_mmc.o 259 CC drivers/dfu/dfu_ram.o 260 CC drivers/dfu/dfu_tftp.o 261 LD drivers/dfu/built-in.o 262 LD drivers/firmware/built-in.o 263 CC drivers/input/input.o 264 LD drivers/input/built-in.o 265 LD drivers/mailbox/built-in.o 266 LD drivers/memory/built-in.o 267 LD drivers/misc/built-in.o 268 CC drivers/mmc/mmc.o 269 CC drivers/mmc/mmc_legacy.o 270 CC drivers/mmc/mmc_write.o 271 CC drivers/mmc/omap_hsmmc.o 272 LD drivers/mmc/built-in.o 273 LD drivers/pcmcia/built-in.o 274 LD drivers/phy/marvell/built-in.o 275 LD drivers/pwm/built-in.o 276 LD drivers/reset/built-in.o 277 CC drivers/rtc/date.o 278 LD drivers/rtc/built-in.o 279 LD drivers/scsi/built-in.o 280 LD drivers/soc/built-in.o 281 LD drivers/sound/built-in.o 282 LD drivers/spmi/built-in.o 283 LD drivers/sysreset/built-in.o 284 LD drivers/thermal/built-in.o 285 LD drivers/tpm/built-in.o 286 LD drivers/video/bridge/built-in.o 287 LD drivers/video/sunxi/built-in.o 288 LD drivers/video/built-in.o 289 CC drivers/watchdog/omap_wdt.o 290 LD drivers/watchdog/built-in.o 291 LD drivers/built-in.o 292 LD drivers/dma/built-in.o 293 CC drivers/gpio/gpio-uclass.o 294 CC drivers/gpio/omap_gpio.o 295 LD drivers/gpio/built-in.o 296 CC drivers/i2c/i2c_core.o 297 CC drivers/i2c/omap24xx_i2c.o 298 LD drivers/i2c/built-in.o 299 CC drivers/mtd/mtdcore.o 300 CC drivers/mtd/mtd_uboot.o 301 LD drivers/mtd/built-in.o 302 LD drivers/mtd/onenand/built-in.o 303 CC drivers/mtd/spi/sf_probe.o 304 CC drivers/mtd/spi/spi_flash.o 305 CC drivers/mtd/spi/spi_flash_ids.o 306 CC drivers/mtd/spi/sf.o 307 LD drivers/mtd/spi/built-in.o 308 CC drivers/net/cpsw.o 309 CC drivers/net/cpsw-common.o 310 LD drivers/net/built-in.o 311 CC drivers/net/phy/phy.o 312 CC drivers/net/phy/atheros.o 313 CC drivers/net/phy/smsc.o 314 LD drivers/net/phy/built-in.o 315 LD drivers/pci/built-in.o 316 LD drivers/power/built-in.o 317 LD drivers/power/battery/built-in.o 318 LD drivers/power/domain/built-in.o 319 LD drivers/power/fuel_gauge/built-in.o 320 LD drivers/power/mfd/built-in.o 321 CC drivers/power/pmic/pmic_tps65217.o 322 CC drivers/power/pmic/pmic_tps65910.o 323 LD drivers/power/pmic/built-in.o 324 LD drivers/power/regulator/built-in.o 325 CC drivers/serial/serial-uclass.o 326 CC drivers/serial/ns16550.o 327 LD drivers/serial/built-in.o 328 CC drivers/spi/spi.o 329 CC drivers/spi/omap3_spi.o 330 LD drivers/spi/built-in.o 331 LD drivers/usb/common/built-in.o 332 LD drivers/usb/dwc3/built-in.o 333 LD drivers/usb/emul/built-in.o 334 LD drivers/usb/eth/built-in.o 335 CC drivers/usb/gadget/epautoconf.o 336 CC drivers/usb/gadget/config.o 337 CC drivers/usb/gadget/usbstring.o 338 CC drivers/usb/gadget/g_dnl.o 339 CC drivers/usb/gadget/f_dfu.o 340 CC drivers/usb/gadget/f_fastboot.o 341 CC drivers/usb/gadget/ether.o 342 CC drivers/usb/gadget/rndis.o 343 LD drivers/usb/gadget/built-in.o 344 LD drivers/usb/gadget/udc/built-in.o 345 LD drivers/usb/host/built-in.o 346 CC drivers/usb/musb-new/musb_gadget.o 347 CC drivers/usb/musb-new/musb_gadget_ep0.o 348 CC drivers/usb/musb-new/musb_core.o 349 CC drivers/usb/musb-new/musb_uboot.o 350 CC drivers/usb/musb-new/musb_host.o 351 CC drivers/usb/musb-new/musb_dsps.o 352 LD drivers/usb/musb-new/built-in.o 353 LD drivers/usb/musb/built-in.o 354 LD drivers/usb/phy/built-in.o 355 LD drivers/usb/ulpi/built-in.o 356 CC env/common.o 357 CC env/env.o 358 CC env/attr.o 359 CC env/callback.o 360 CC env/flags.o 361 CC env/mmc.o 362 LD env/built-in.o 363 CC fs/fs.o 364 CC fs/ext4/ext4fs.o 365 CC fs/ext4/ext4_common.o 366 CC fs/ext4/dev.o 367 CC fs/ext4/ext4_write.o 368 CC fs/ext4/ext4_journal.o 369 CC fs/ext4/crc16.o 370 LD fs/ext4/built-in.o 371 CC fs/fat/fat_write.o 372 LD fs/fat/built-in.o 373 CC fs/fs_internal.o 374 LD fs/built-in.o 375 CC lib/efi_loader/efi_image_loader.o 376 CC lib/efi_loader/efi_boottime.o 377 CC lib/efi_loader/efi_runtime.o 378 CC lib/efi_loader/efi_console.o 379 CC lib/efi_loader/efi_memory.o 380 CC lib/efi_loader/efi_device_path_to_text.o 381 CC lib/efi_loader/efi_device_path.o 382 CC lib/efi_loader/efi_file.o 383 CC lib/efi_loader/efi_variable.o 384 CC lib/efi_loader/efi_bootmgr.o 385 CC lib/efi_loader/efi_watchdog.o 386 CC lib/efi_loader/efi_disk.o 387 CC lib/efi_loader/efi_net.o 388 CC lib/efi_loader/efi_smbios.o 389 LD lib/efi_loader/built-in.o 390 CC lib/efi_loader/helloworld.o 391 LD lib/efi_loader/helloworld_efi.so 392 OBJCOPY lib/efi_loader/helloworld.efi 393 rm lib/efi_loader/helloworld_efi.so lib/efi_loader/helloworld.o 394 LD lib/efi_selftest/built-in.o 395 CC lib/libfdt/fdt.o 396 CC lib/libfdt/fdt_wip.o 397 CC lib/libfdt/fdt_strerror.o 398 CC lib/libfdt/fdt_sw.o 399 CC lib/libfdt/fdt_empty_tree.o 400 CC lib/libfdt/fdt_addresses.o 401 CC lib/libfdt/fdt_overlay.o 402 CC lib/libfdt/fdt_ro.o 403 CC lib/libfdt/fdt_rw.o 404 CC lib/libfdt/fdt_region.o 405 LD lib/libfdt/built-in.o 406 CC lib/lzo/lzo1x_decompress.o 407 LD lib/lzo/built-in.o 408 CC lib/zlib/zlib.o 409 LD lib/zlib/built-in.o 410 CC lib/charset.o 411 CC lib/crc7.o 412 CC lib/crc8.o 413 CC lib/crc16.o 414 CC lib/fdtdec_common.o 415 CC lib/smbios.o 416 CC lib/initcall.o 417 CC lib/lmb.o 418 CC lib/ldiv.o 419 CC lib/md5.o 420 CC lib/net_utils.o 421 CC lib/qsort.o 422 CC lib/rc4.o 423 CC lib/list_sort.o 424 CC lib/sha1.o 425 CC lib/sha256.o 426 CC lib/gunzip.o 427 CC lib/hashtable.o 428 CC lib/errno.o 429 CC lib/display_options.o 430 CC lib/crc32.o 431 CC lib/ctype.o 432 CC lib/div64.o 433 CC lib/hang.o 434 CC lib/linux_compat.o 435 CC lib/linux_string.o 436 CC lib/membuff.o 437 CC lib/slre.o 438 CC lib/string.o 439 CC lib/tables_csum.o 440 CC lib/time.o 441 CC lib/uuid.o 442 CC lib/rand.o 443 CC lib/vsprintf.o 444 CC lib/panic.o 445 CC lib/strto.o 446 CC lib/strmhz.o 447 LD lib/built-in.o 448 CC net/checksum.o 449 CC net/arp.o 450 CC net/bootp.o 451 CC net/eth_legacy.o 452 CC net/eth_common.o 453 CC net/net.o 454 CC net/nfs.o 455 CC net/ping.o 456 CC net/tftp.o 457 LD net/built-in.o 458 LD test/built-in.o 459 CC test/dm/cmd_dm.o 460 LD test/dm/built-in.o 461 CC examples/standalone/stubs.o 462 LD examples/standalone/libstubs.o 463 CC examples/standalone/hello_world.o 464 LD examples/standalone/hello_world 465 OBJCOPY examples/standalone/hello_world.srec 466 OBJCOPY examples/standalone/hello_world.bin 467 LDS u-boot.lds 468 LD u-boot 469 OBJCOPY u-boot-nodtb.bin 470 COPY u-boot.bin 471 MKIMAGE u-boot.img 472 OBJCOPY u-boot.srec 473 SYM u-boot.sym 474 /bin/sh: 1: bc: not found 475 CC spl/arch/arm/mach-omap2/am33xx/clock_am33xx.o 476 CC spl/arch/arm/mach-omap2/am33xx/clock.o 477 CC spl/arch/arm/mach-omap2/am33xx/sys_info.o 478 CC spl/arch/arm/mach-omap2/am33xx/ddr.o 479 CC spl/arch/arm/mach-omap2/am33xx/emif4.o 480 CC spl/arch/arm/mach-omap2/am33xx/board.o 481 CC spl/arch/arm/mach-omap2/am33xx/mux.o 482 CC spl/arch/arm/mach-omap2/am33xx/prcm-regs.o 483 CC spl/arch/arm/mach-omap2/am33xx/hw_data.o 484 CC spl/arch/arm/mach-omap2/am33xx/fdt.o 485 CC spl/arch/arm/mach-omap2/am33xx/clk_synthesizer.o 486 LD spl/arch/arm/mach-omap2/am33xx/built-in.o 487 CC spl/arch/arm/mach-omap2/reset.o 488 CC spl/arch/arm/mach-omap2/timer.o 489 CC spl/arch/arm/mach-omap2/utils.o 490 CC spl/arch/arm/mach-omap2/sysinfo-common.o 491 CC spl/arch/arm/mach-omap2/omap-cache.o 492 CC spl/arch/arm/mach-omap2/boot-common.o 493 AS spl/arch/arm/mach-omap2/lowlevel_init.o 494 CC spl/arch/arm/mach-omap2/mem-common.o 495 CC spl/arch/arm/mach-omap2/fdt-common.o 496 LD spl/arch/arm/mach-omap2/built-in.o 497 CC spl/arch/arm/cpu/armv7/cache_v7.o 498 AS spl/arch/arm/cpu/armv7/cache_v7_asm.o 499 CC spl/arch/arm/cpu/armv7/cpu.o 500 CC spl/arch/arm/cpu/armv7/cp15.o 501 CC spl/arch/arm/cpu/armv7/syslib.o 502 AS spl/arch/arm/cpu/armv7/lowlevel_init.o 503 LD spl/arch/arm/cpu/armv7/built-in.o 504 AS spl/arch/arm/cpu/armv7/start.o 505 LD spl/arch/arm/cpu/built-in.o 506 AS spl/arch/arm/lib/vectors.o 507 AS spl/arch/arm/lib/crt0.o 508 AS spl/arch/arm/lib/setjmp.o 509 CC spl/arch/arm/lib/spl.o 510 CC spl/arch/arm/lib/zimage.o 511 CC spl/arch/arm/lib/bootm-fdt.o 512 AS spl/arch/arm/lib/memset.o 513 AS spl/arch/arm/lib/memcpy.o 514 CC spl/arch/arm/lib/sections.o 515 CC spl/arch/arm/lib/stack.o 516 CC spl/arch/arm/lib/interrupts.o 517 CC spl/arch/arm/lib/reset.o 518 CC spl/arch/arm/lib/cache.o 519 CC spl/arch/arm/lib/cache-cp15.o 520 CC spl/arch/arm/lib/psci-dt.o 521 LD spl/arch/arm/lib/built-in.o 522 AS spl/arch/arm/lib/ashldi3.o 523 AS spl/arch/arm/lib/ashrdi3.o 524 CC spl/arch/arm/lib/div0.o 525 AS spl/arch/arm/lib/div64.o 526 AS spl/arch/arm/lib/lib1funcs.o 527 AS spl/arch/arm/lib/lshrdi3.o 528 AS spl/arch/arm/lib/muldi3.o 529 AS spl/arch/arm/lib/uldivmod.o 530 AR spl/arch/arm/lib/lib.a 531 CC spl/arch/arm/lib/eabi_compat.o 532 AS spl/arch/arm/lib/crt0_arm_efi.o 533 CC spl/arch/arm/lib/reloc_arm_efi.o 534 CC spl/board/ti/am335x/mux.o 535 CC spl/board/ti/am335x/board.o 536 LD spl/board/ti/am335x/built-in.o 537 CC spl/board/ti/common/board_detect.o 538 LD spl/board/ti/common/built-in.o 539 CC spl/common/spl/spl.o 540 CC spl/common/spl/spl_ymodem.o 541 CC spl/common/spl/spl_mmc.o 542 CC spl/common/spl/spl_fat.o 543 CC spl/common/spl/spl_ext.o 544 LD spl/common/spl/built-in.o 545 CC spl/common/init/board_init.o 546 LD spl/common/init/built-in.o 547 CC spl/common/xyzModem.o 548 CC spl/common/fdt_support.o 549 CC spl/common/console.o 550 CC spl/common/dlmalloc.o 551 CC spl/common/malloc_simple.o 552 CC spl/common/image.o 553 CC spl/common/image-android.o 554 CC spl/common/image-fdt.o 555 CC spl/common/memsize.o 556 CC spl/common/stdio.o 557 CC spl/common/cli.o 558 CC spl/common/dfu.o 559 CC spl/common/command.o 560 CC spl/common/s_record.o 561 LD spl/common/built-in.o 562 CC spl/cmd/nvedit.o 563 LD spl/cmd/built-in.o 564 CC spl/env/common.o 565 CC spl/env/env.o 566 CC spl/env/attr.o 567 CC spl/env/flags.o 568 CC spl/env/callback.o 569 CC spl/env/mmc.o 570 LD spl/env/built-in.o 571 CC spl/lib/sha1.o 572 CC spl/lib/sha256.o 573 CC spl/lib/libfdt/fdt.o 574 CC spl/lib/libfdt/fdt_wip.o 575 CC spl/lib/libfdt/fdt_strerror.o 576 CC spl/lib/libfdt/fdt_sw.o 577 CC spl/lib/libfdt/fdt_empty_tree.o 578 CC spl/lib/libfdt/fdt_addresses.o 579 CC spl/lib/libfdt/fdt_overlay.o 580 CC spl/lib/libfdt/fdt_ro.o 581 CC spl/lib/libfdt/fdt_rw.o 582 CC spl/lib/libfdt/fdt_region.o 583 LD spl/lib/libfdt/built-in.o 584 CC spl/lib/crc16.o 585 CC spl/lib/hashtable.o 586 CC spl/lib/errno.o 587 CC spl/lib/display_options.o 588 CC spl/lib/crc32.o 589 CC spl/lib/ctype.o 590 CC spl/lib/div64.o 591 CC spl/lib/hang.o 592 CC spl/lib/linux_compat.o 593 CC spl/lib/linux_string.o 594 CC spl/lib/membuff.o 595 CC spl/lib/slre.o 596 CC spl/lib/string.o 597 CC spl/lib/tables_csum.o 598 CC spl/lib/time.o 599 CC spl/lib/uuid.o 600 CC spl/lib/rand.o 601 CC spl/lib/tiny-printf.o 602 CC spl/lib/panic.o 603 CC spl/lib/strto.o 604 LD spl/lib/built-in.o 605 CC spl/disk/part.o 606 CC spl/disk/part_dos.o 607 CC spl/disk/part_iso.o 608 CC spl/disk/part_efi.o 609 LD spl/disk/built-in.o 610 CC spl/drivers/block/blk_legacy.o 611 LD spl/drivers/block/built-in.o 612 CC spl/drivers/core/device.o 613 CC spl/drivers/core/fdtaddr.o 614 CC spl/drivers/core/lists.o 615 CC spl/drivers/core/root.o 616 CC spl/drivers/core/uclass.o 617 CC spl/drivers/core/util.o 618 CC spl/drivers/core/dump.o 619 LD spl/drivers/core/built-in.o 620 CC spl/drivers/gpio/gpio-uclass.o 621 CC spl/drivers/gpio/omap_gpio.o 622 LD spl/drivers/gpio/built-in.o 623 CC spl/drivers/i2c/i2c_core.o 624 CC spl/drivers/i2c/omap24xx_i2c.o 625 LD spl/drivers/i2c/built-in.o 626 CC spl/drivers/mmc/mmc.o 627 CC spl/drivers/mmc/mmc_legacy.o 628 CC spl/drivers/mmc/omap_hsmmc.o 629 LD spl/drivers/mmc/built-in.o 630 LD spl/drivers/power/built-in.o 631 CC spl/drivers/power/pmic/pmic_tps65217.o 632 CC spl/drivers/power/pmic/pmic_tps65910.o 633 LD spl/drivers/power/pmic/built-in.o 634 LD spl/drivers/power/regulator/built-in.o 635 CC spl/drivers/serial/serial-uclass.o 636 CC spl/drivers/serial/ns16550.o 637 LD spl/drivers/serial/built-in.o 638 CC spl/drivers/usb/musb-new/musb_gadget.o 639 CC spl/drivers/usb/musb-new/musb_gadget_ep0.o 640 CC spl/drivers/usb/musb-new/musb_core.o 641 CC spl/drivers/usb/musb-new/musb_uboot.o 642 CC spl/drivers/usb/musb-new/musb_host.o 643 CC spl/drivers/usb/musb-new/musb_dsps.o 644 LD spl/drivers/usb/musb-new/built-in.o 645 CC spl/drivers/watchdog/omap_wdt.o 646 LD spl/drivers/watchdog/built-in.o 647 LD spl/drivers/built-in.o 648 LD spl/dts/built-in.o 649 CC spl/fs/ext4/ext4fs.o 650 CC spl/fs/ext4/ext4_common.o 651 CC spl/fs/ext4/dev.o 652 CC spl/fs/ext4/ext4_write.o 653 CC spl/fs/ext4/ext4_journal.o 654 CC spl/fs/ext4/crc16.o 655 LD spl/fs/ext4/built-in.o 656 CC spl/fs/fat/fat_write.o 657 LD spl/fs/fat/built-in.o 658 CC spl/fs/fs_internal.o 659 LD spl/fs/built-in.o 660 LDS spl/u-boot-spl.lds 661 LD spl/u-boot-spl 662 OBJCOPY spl/u-boot-spl-nodtb.bin 663 COPY spl/u-boot-spl.bin 664 MKIMAGE MLO 665 MKIMAGE MLO.byteswap 666 CHK include/config.h 667 CFG u-boot.cfg 668 CFGCHK u-boot.cfg
以spl/打頭的都是spl相關的編譯,在輸出的后半部分,大家可以看到 475行和125 行編譯的是同一個C文件,一個是u-boot,一個是u-boot-spl
SPL的其他配置項
由於現在u-boot同時使用Kconfig和老的頭文件方式進行配置,下面很多配置在BBB中仍然是在頭文件中配置的。
- CONFIG_SPL_TEXT_BASE SPL的入口地址
- CONFIG_SPL_LDSCRIPT SPL的鏈接腳本
除了板子特有的代碼外,如果要使用u-boot通用的庫或驅動,還需要定義 CONFIG_SPL_XXX_SUPPORT,當前支持如下配置
- CONFIG_SPL_LIBCOMMON_SUPPORT (common/libcommon.o)
- CONFIG_SPL_LIBDISK_SUPPORT (disk/libdisk.o)
- CONFIG_SPL_I2C_SUPPORT (drivers/i2c/libi2c.o)
- CONFIG_SPL_GPIO_SUPPORT (drivers/gpio/libgpio.o)
- CONFIG_SPL_MMC_SUPPORT (drivers/mmc/libmmc.o)
- CONFIG_SPL_SERIAL_SUPPORT (drivers/serial/libserial.o)
- CONFIG_SPL_SPI_FLASH_SUPPORT (drivers/mtd/spi/libspi_flash.o)
- CONFIG_SPL_SPI_SUPPORT (drivers/spi/libspi.o)
- CONFIG_SPL_FAT_SUPPORT (fs/fat/libfat.o)
- CONFIG_SPL_EXT_SUPPORT
- CONFIG_SPL_LIBGENERIC_SUPPORT (lib/libgeneric.o)
- CONFIG_SPL_POWER_SUPPORT (drivers/power/libpower.o)
- CONFIG_SPL_NAND_SUPPORT (drivers/mtd/nand/libnand.o)
- CONFIG_SPL_DRIVERS_MISC_SUPPORT (drivers/misc)
- CONFIG_SPL_DMA_SUPPORT (drivers/dma/libdma.o)
- CONFIG_SPL_POST_MEM_SUPPORT (post/drivers/memory.o)
- CONFIG_SPL_NAND_LOAD (drivers/mtd/nand/nand_spl_load.o)
- CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o)
- CONFIG_SPL_RAM_DEVICE (common/spl/spl.c)
- CONFIG_SPL_WATCHDOG_SUPPORT (drivers/watchdog/libwatchdog.o)
SPL 編譯分析
u-boot在最近幾年引入了Linux內核的Kconfig方式,主要介紹在源代碼的 doc/README.kconfig 中,u-boot的目標是把所有配置都放到Kconfig中去,但是目前仍然有大量配置是寫在頭文件中的。在目前的情況下,C文件中可使用的配置文件是
- include/generated/autoconf.h (generated by Kconfig for Normal)
- include/configs/<target>.h (exists for all boards) 例如:bbb的target為 am335x_evm
Makefile中可使用的配置文件是
- include/config/auto.conf (generated by Kconfig)
- include/autoconf.mk (generated by the old config for Normal)
- spl/include/autoconfig.mk (generated by the old config for SPL)
- tpl/include/autoconfig.mk (generated by the old config for TPL) (注意:TPL跟SPL差不多,是第三級程序加載器,也是一個精簡版的u-boot,很少用到,參見 doc/README.TPL)
板級相關的代碼都在哪里
- CONFIG_SYS_CPU="cpu" 將會編譯 arch/<arch>/cpu/<cpu>
- CONFIG_SYS_SOC="soc" 將會編譯 arch/<arch>/cpu/<cpu>/<soc>
- CONFIG_SYS_VENDOR="vendor" 將會編譯 board/<vendor>/common/* 和 board/<vendor>/<board>/*
- CONFIG_SYS_BOARD="board" 將會編譯 board/<board>/* (或 board/<vendor>/<board>/* 如果 CONFIG_SYS_VENDOR 也定義了)
- CONFIG_SYS_CONFIG_NAME="target" 將包含 include/configs/<target>.h
- 在 arch/<arch>/Kconfig 或 arch/<arch>/*/Kconfig 中應 source 板級相關的 Kconfig 文件來編譯更多的文件
對於BBB開發板來說,可以查看 am335x_boneblack_defconfig:
- <arch> = arm
- <cpu> = armv7
- <soc> = am33xx
- <vendor> = ti
- <board> = am335x
- <target> = am335x_evm
對照上面,BBB板級相關的代碼包括以下文件夾中
- arch/arm/cpu/armv7
- arch/arm/cpu/armv7/am33xx(無此文件夾)取而代之的是 arch/arm/mach-omap2/am33xx ,這是因為 arch/arm/mach-omap2/Kconfig 中 source 了 arch/arm/mach-omap2/am33xx/Kconfig 和 board/ti/am335x/Kconfig
- board/ti/common
- board/ti/am335x
- 配置的頭文件為 includes/configs/am335x_evm.h
對照下上面實際編譯輸出,基本上差不多,除了多了一個 arch/arm/mach-omap2/* ,參見下文 (machine-$(CONFIG_ARCH_OMAP2PLUS))。
Makefile簡述
u-boot根目錄中的Makefile包含如下語句
ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin spl/u-boot-spl.bin: spl/u-boot-spl @: spl/u-boot-spl: tools prepare \ $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb) \ $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_TPL_OF_PLATDATA),dts/dt.dtb) $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
而Makefile.spl首先包含了源代碼樹根目錄的 config.mk,這個文件根據配置定義了ARCH、CPU、SOC、BOARD、VENDOR、CPUDIR、BOARDDIR等板級相關的變量,並包含了 ARCH、CPU、SOC、BOARD等板級相關的文件夾中的config.mk,以便添加或覆蓋默認配置。配置確定后,Makefile.spl中定義了spl的各依賴,其中libs-y是spl需要編譯的庫(即子文件夾)
u-boot-spl-dirs := $(patsubst %/,%,$(filter %/, $(libs-y)))
u-boot-spl-init := $(head-y)
# 注意:最后libs-y被轉換為對應目錄的 built-in.o,參見下文中對 Makefile.build 的分析
libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) u-boot-spl-main := $(libs-y) $(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \ $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE $(call if_changed,u-boot-spl)
# May be overridden by arch/$(ARCH)/config.mk
# 這是 $(call if_changed,u-boot-spl) 實際執行的命令
quiet_cmd_u-boot-spl ?= LD $@
cmd_u-boot-spl ?= (cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
$(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \
$(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
$(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \
--end-group \
$(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN))
其中 link script的查找方法是
ifeq ($(wildcard $(LDSCRIPT)),) LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot-spl.lds endif ifeq ($(wildcard $(LDSCRIPT)),) LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot-spl.lds endif ifeq ($(wildcard $(LDSCRIPT)),) LDSCRIPT := $(srctree)/arch/$(ARCH)/cpu/u-boot-spl.lds endif ifeq ($(wildcard $(LDSCRIPT)),) $(error could not find linker script) endif
即,依次查找 BOARD、CPU、ARCH目錄,第一個發現的u-boot-spl.lds文件。
大部分libs都是在Makefile.spl中直接定義的,如下
libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/) libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/ libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/ libs-y += common/init/ # Special handling for a few options which support SPL/TPL ifeq ($(CONFIG_TPL_BUILD),y) libs-$(CONFIG_TPL_LIBCOMMON_SUPPORT) += common/ cmd/ env/ libs-$(CONFIG_TPL_LIBGENERIC_SUPPORT) += lib/ else libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ cmd/ env/ libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/ endif libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/ libs-y += drivers/ libs-$(CONFIG_SPL_USB_GADGET_SUPPORT) += drivers/usb/dwc3/ libs-y += dts/ libs-y += fs/ libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/ libs-$(CONFIG_SPL_NET_SUPPORT) += net/
但是有一部分是ARCH和CPU相關的是在 arch/arm/Makefile中定義的
# head-y 也是在這個文件中定義的
head-y := arch/arm/cpu/$(CPU)/start.o # 注意:這就是為什么BBB會編譯 mach-omap2 文件夾了 machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) libs-y += $(machdirs) libs-y += arch/arm/cpu/$(CPU)/ libs-y += arch/arm/cpu/ libs-y += arch/arm/lib/
最后要說明下,這些lib-y的子文件夾是如何編譯的
$(u-boot-spl-dirs): $(u-boot-spl-platdata) $(Q)$(MAKE) $(build)=$@
上面這句話非常簡潔,但包含的內容卻很多,注意是 $(build)=$@ 而不是 build=$@,build是kbuild.include中定義的一個變量,其值是
build := -f $(srctree)/scripts/Makefile.build obj
對u-boot-spl-dirs中的每一個子目錄,展開了之后是
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj=目錄
Makefile.build是Kbuild體系的核心文件,文件夾的編譯都是通過這個文件來完成的,理解這個文件我認為需要知道幾個要點:
- 這個文件包含了 Kbuild.include 和 Makefile.lib,這兩個文件定義了很多實用函數、變量和通用的規則,一般位置找不到的東西都在這里
- 這個文件包含了 obj=目錄 中的 Kbuild或Makefile文件,這樣我們再寫某個目錄中的Kbuild或Makefile時就比較簡單了,我們只需要定義
- obj-y:本目錄中的源文件
- subdir-y:需要遞歸編譯的子目錄
- extra-y:額外要執行的編譯目標
- 一個目錄中的所有源文件及子目錄的編譯結果最終會LD成一個 built-in.o
- subdir-y中的目錄又會使用 Makefile.build 遞歸編譯
# 至少有lib-y lib-m lib- 其中一個時才生成 lib.a
ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) lib-target := $(obj)/lib.a endif
# 至少有obj-y obj-m obj- subdir-m lib-y lib-m lib- 其中一個時才生成 built-in.o ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),) builtin-target := $(obj)/built-in.o endif modorder-target := $(obj)/modules.order # We keep a list of all modules in $(MODVERDIR)
# KBUILD_BUILTIN 在頂層Makefile賦為了1,u-boot中不需要module,所以KBUILD_MODULES為0 __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \ $(subdir-ym) $(always) @:
以上這個部分我認為比較重要,未指定目標時,Makefile.build的默認目標是 __build,這個__build依賴
- built-in.o
- lib.a
- extra-y
- subdir-ym:這是子目錄
SPL執行分析
(源代碼根目錄下 README 文件中有一節Board Initialisation Flow專門講了啟動流程)
SPL編譯分析結束后,我們就知道了SPL由哪些源文件組成,分析起來要方便多了。首先當然是從head-y開始,即 arch/arm/cpu/armv7/start.S
- save_boot_params:通過weak方式調用了 arch/arm/omach-omap2/lowlevel_init.S中的同名函數(存了r0到RAM)(暫時還沒有搞清r0是啥)
- 關中斷,進入SVC模式
- cpu_init_cp15:Cache、MMU、TLB操作等(該清清,該禁禁,I-Cache一般是打開)
- cpu_init_crit:調用 lowlevel_init,BBB板級未定義lowlevel_init,於是就調用了 arch/arm/cpu/armv7/lowlevel_init.S 中的 lowlevel_init函數,對SPL來說基本沒干啥
- _main:這個函數是重頭戲,定義在 arch/arm/lib/crt0.S中,這個函數大概流程是這樣的
- 初始化GD
- board_init_f
- 正常的u-boot此處會進行relocate,SPL不會,但是SPL可能會改變棧和GD的位置(參見 CONFIG_SPL_FRAMEWORK,common/spl/spl.c中的spl_relocate_stack_gd函數)
- 清零bss區
- board_init_r
GD(struct global_data)
為了簡單起見,u-boot有一個全局的結構體數據,稱為GD(指針為gd),很多數據都會丟到這個結構體里。
typedef struct global_data { //... struct arch_global_data arch; // ... } gd_t;
這個結構體的定義在源代碼目錄的 include/asm-generic/global_data.h,這個文件應被arch的同名文件包含,以便可以定義不同的 struct arch_global_data 結構體,對於arm來說是 arch/arm/include/asm/global_data.h ,使用時 采用 #include<asm/global_data.h>的方式就可以包含不同arch的同名文件了。
這么重要的結構體是在_main的一開始就被初始化為0了,代碼在 common/init/board_init.c中的 board_init_f_alloc_reserve/board_init_f_init_reserve 兩個函數里,通過在棧頂預留內存來達到給GD開辟空間的目的(因棧是向下增長的,所有不會和棧沖突)。
注:在arm架構中,gd的指針被賦給了r9寄存器,在需要使用gd地方,通過全局聲明r9,使編譯器不會使用r9寄存器作為臨時變量,加快gd的訪問速度。
https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.htm 在 arch/arm/config.mk 中 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \ -fno-common -ffixed-r9 注意: -ffixed-r9 就是上述鏈接中的 -ffixed-reg ,所有函數都不可以使用r9寄存器
board_init_f
GD初始化完成之后,就會調用 board_init_f,這個函數的目的是使board_init_r可以運行,主要是初始化DRAM和console串口,要注意下這個函數的運行環境:
- GD指針可使用,因為GD已經初始化
- 棧是在SRAM中的
- BSS還未清零,因為所有全局或靜態變量都是不可以訪問的,只能訪問局部變量和GD
雖說這個函數以board打頭,但是相似的板子可能會定義一個初始化的流程,在流程中大量使用虛函數和配置來抽象不同的板子。BBB的board_init_f是在 arch/arm/march-omap2/am33xx/board.c 中
#ifdef CONFIG_SPL_BUILD void board_init_f(ulong dummy) { hw_data_init(); early_system_init(); board_early_init_f(); sdram_init(); /* dram_init must store complete ramsize in gd->ram_size */ gd->ram_size = get_ram_size( (void *)CONFIG_SYS_SDRAM_BASE, CONFIG_MAX_RAM_BANK_SIZE); } #endif
board_init_r
這個函數用來實現主要的代碼邏輯,對於SPL來說,主要函數都是在 common/spl/spl.c 中實現了,具體大家直接看代碼就是了
falcon
參見 doc/README.falcon,大概就是SPL=>u-boot=>Linux這個流程有點慢,falcon的功能就是不啟動u-boot,直接啟動Linux,相關的配置項是 CONFIG_SPL_OS_BOOT
這篇文章就寫這么多了,把這些搞明白了,u-boot-spl就大體上理解了,更詳細的還得大家自己回去讀代碼了,共勉!