Jagan Teki U Boot From Scratch v2019 01 Edition v2
Jagan Teki U Boot From Scratch v2019 01 Edition v2
Jagan Teki
FOSDEM - 2019
Jagan Teki
➔ JagannadhaSutradharudu Teki
➔ Enthusiastic Linux kernel hacker
➔ U-Boot Maintainer for SPI, SPI-FLASH, Allwinner sunXi SoC
➔ Buildroot, Yocto contributor
➔ Heading to Amarula Solutions India
2
Agenda
➔ U-Boot, In a NutShell
➔ Image boot
➔ Features
➔ Future plans
3
U-Boot, In a NutShell
➔ History
➔ Community
➔ Hardware support
➔ U-Boot
➔ Source
➔ Source tree
➔ Build process
➔ Boot Sequence
➔ Loading sources
➔ Debug
➔ Tools
➔ Testing
4
History
5
Community
➔ On average over 25+ employers and 120+ developers contributing every release
➔ Number of talks on various conferences
ged to 3
Development process:
w c h a n
no
35+ Custodian/Maintainer for various subsystems Note: RC h 3 weeks MW
➔ wit
➔ Release cycle months,
Release cycle
(2 months)
➔ Workflow
ML
Developer Reviews Maintainer PR Master
send patch (maintainer, any) repo repo
6
Hardware support
Architecture/SoC:
➔ ARM
◆ 32-bit: Aspeed, Altera, Allwinner, Atmel, Broadcom, Qemu, Qualcomm, Marvell, NXP,
Rockchip, STM32, Tegra, TI, UniPhier, Xilinx
◆ 64-bit: Allwinner, Marvell, NXP, Rockchip, Tegra, UniPhier, Xilinx
Boards:
7
U-Boot
U-Boot proper
U-Boot U-Boot proper
Bootloader U-Boot SPL
SoC Loader SPL
TPL
8
U-Boot build
Example of building vyasa RK3288 board, which is ARM platform with arm-linux-gnueabi
9
U-Boot tree
10
Build process
1. CC spl/arch/arm/mach-rockchip/sdram_common.o
1. scripts/kconfig/conf --syncconfig Kconfig
2. CC spl/arch/arm/mach-rockchip/rk_timer.o
2. CHK include/config.h
3. CC spl/arch/arm/mach-rockchip/rk3288/clk_rk3288.o
3. UPD include/config.h
4. CC spl/arch/arm/mach-rockchip/rk3288/rk3288.o
4. CFG u-boot.cfg
5. CC spl/arch/arm/mach-rockchip/rk3288/syscon_rk3288.o
5. GEN include/autoconf.mk
6. CC spl/arch/arm/mach-rockchip/bootrom.o
6. GEN include/autoconf.mk.dep
7. CC spl/arch/arm/mach-rockchip/rk3288-board-spl.o
7. CFG spl/u-boot.cfg
8. CC spl/arch/arm/cpu/armv7/cache_v7.o
8. GEN spl/include/autoconf.mk
9. CC spl/arch/arm/cpu/armv7/cpu.o
9. CFG tpl/u-boot.cfg
10. AS spl/arch/arm/cpu/armv7/lowlevel_init.o
10. GEN tpl/include/autoconf.mk
11. AS spl/arch/arm/cpu/armv7/start.o
11. CHK include/config/uboot.release
12. LD spl/u-boot-spl
12. UPD include/config/uboot.release
13. OBJCOPY spl/u-boot-spl-nodtb.bin
13. CHK include/generated/version_autogenerated.h
14. COPY spl/u-boot-spl.dtb
14. UPD include/generated/version_autogenerated.h
15. CAT spl/u-boot-spl-dtb.bin
15. CHK include/generated/timestamp_autogenerated.h
16. COPY spl/u-boot-spl.bin
16.
17.
17. LD arch/arm/cpu/built-in.o
18. CC tpl/arch/arm/mach-rockchip/sdram_common.o
18. CC arch/arm/cpu/armv7/cache_v7.o
19. CC tpl/arch/arm/mach-rockchip/rk_timer.o
19. AS arch/arm/cpu/armv7/cache_v7_asm.o
20. CC tpl/arch/arm/mach-rockchip/rk3288/clk_rk3288.o
20. CC arch/arm/cpu/armv7/cpu.o
21. CC tpl/arch/arm/mach-rockchip/rk3288/rk3288.o
21. CC arch/arm/cpu/armv7/cp15.o
22. CC tpl/arch/arm/mach-rockchip/rk3288/syscon_rk3288.o
22. CC arch/arm/cpu/armv7/syslib.o
23. CC tpl/arch/arm/mach-rockchip/bootrom.o
23. AS arch/arm/cpu/armv7/sctlr.o
24. CC tpl/arch/arm/mach-rockchip/rk3288-board-tpl.o
24. AS arch/arm/cpu/armv7/lowlevel_init.o
25. CC tpl/arch/arm/cpu/armv7/cache_v7.o
25. LD arch/arm/cpu/armv7/built-in.o
26. AS tpl/arch/arm/cpu/armv7/cache_v7_asm.o
26. AS arch/arm/cpu/armv7/start.o
27. CC tpl/arch/arm/cpu/armv7/cpu.o
27. CC arch/arm/lib/eabi_compat.o
28. CC tpl/arch/arm/cpu/armv7/cp15.o
28. AS arch/arm/lib/crt0_arm_efi.o
29. CC tpl/arch/arm/cpu/armv7/syslib.o
29. CC arch/arm/lib/reloc_arm_efi.o
30. AS tpl/arch/arm/cpu/armv7/lowlevel_init.o
30. CC arch/arm/mach-rockchip/boot_mode.o
31. AS tpl/arch/arm/cpu/armv7/start.o
31. CC arch/arm/mach-rockchip/rk3288-board.o
32. LDS tpl/u-boot-spl.lds
32. CC arch/arm/mach-rockchip/sdram_common.o
33. LD tpl/u-boot-tpl
33. CC arch/arm/mach-rockchip/rk_timer.o
34. OBJCOPY tpl/u-boot-tpl-nodtb.bin
34. CC arch/arm/mach-rockchip/rk3288/clk_rk3288.o
35. COPY tpl/u-boot-tpl.bin
35. CC arch/arm/mach-rockchip/rk3288/rk3288.o
36. COPY u-boot.dtb
36. CC arch/arm/mach-rockchip/rk3288/syscon_rk3288.o
37. MKIMAGE u-boot-dtb.img
37. CC board/amarula/vyasa-rk3288/vyasa-rk3288.o
11
U-Boot Sequence
(a) / ATF / OP-TEE
board_init_r
SPL/TPL boot_from_devices() falcon?
malloc()
debug_uart SPL/TPL
clk, pinctrl
gd pmic
alloc/ dram ?? Boot Linux
reserve
(a) board_init_f
U-Boot Proper
U-Boot proper
init_sequence_f
POR reocate init_sequence_r() autoboot?
board_init_r
U-Boot Shell
12
Loading sources
13
Debug
➔ printf
➔ CONFIG_DEBUG
➔ GDB
➔ Early UART (CONFIG_DEBUG_UART)
14
#include <debug_uart.h>
writel(ch, &base->txd);
}
DEBUG_UART_FUNCS
debug_uart_init();
printch('T');
printch('P');
printch('L');
15
Tools
➔ Patman
◆ Manual patch creation, cover-letter, adding maintainers etc can be error-prone.
◆ Patman make above automated
◆ Create patch, insert cover-letter, add maintainer (via ~/.git-mailrc), run checkpatch.pl etc
◆ How to use? tools/patman/README
➔ Buildman
◆ U-Boot builder for multiple commits, branches etc
◆ Replaced by legacy MAKEALL
◆ Understandable output summary / {
◆ Checking image sizes binman {
◆ tools/buildman/README filename = "u-boot-sunxi-with-spl.bin";
➔ Binman pad-byte = <0xff>;
◆ Packaging multiple image components blob {
filename = "spl/sunxi-spl.bin";
};
u-boot-img {
offset = <CONFIG_SPL_PAD_TO>;
};
};
};
16
Testing
➔ travis-ci.org
◆ Automated build environment, with limited run-time, free to use
◆ May take longer duration, if more jobs are initiated
◆ .travis.yml, u-boot travis build plugin
➔ test.py
◆ Pytest framework
◆ Works for sandbox, qemu, some real hardware
◆ Sanity tests for dm code
◆ doc/README.trace
➔ trace
◆ Kind of Linux ftrace
◆ Collect execution and sent to host for analysis
➔ tbot
◆ Execute test cases on boards
◆ Heiko Schocher demo, https://www.youtube.com/watch?v=zfjpj3DLsx4
17
Image Boot
➔ Legacy image
➔ FIT
➔ Verified image
➔ ARM64 ATF
➔ OP-TEE
➔ Secure boot
➔ Falcon mode
➔ EFI boot
➔ Distro boot
18
Legacy Image
xing
x ib l e, inde
fle
? Not
in te grity
hash dition
? No i ty a d
e o f secur
scop
? No
19
FIT (Flattened uImage Tree)
images configurations
data load addr data load addr data load addr config@n
entry point addr entry point addr entry point addr
OS OS OS
20
FIT, contd
21
FIT Complexity ?
ra mdisk
iple k e r nel, dtb,
Mult
ga
bit file, fp
ATF
OPTEE
ge type?
new ima
22
Verified boot
23
Secure boot, Signed
24
Secure boot, Encrypted
25
ATF
Kernel/DTB Kernel/DTB
U-Boot proper
U-Boot proper
ATF
SPL
SPL
BROM BROM
POR POR
26
OP-TEE, ARMv7
27
OP-TEE, ARMv8
28
Falcon mode
Kernel/DTB Kernel/DTB
Kernel/DTB
SPL SPL
from SPL
Boot Linux
oot
BROM BROM
Speed up b
f a lc o n , d uring dryrun
Configur e
POR POR
29
Falcon, is useful?
30
EFI boot
doc/README.uefi
31
Distro boot
# u-boot, extlinux.conf
label linux-5.0.0-rc3
kernel /Image
devicetree /sun50i-a64-amarula-relic.dtb
append console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw
32
U-Boot Features
➔ Kconfig
➔ FDT
➔ OF livetree
➔ FDT Overlay
➔ Driver model
➔ OF platdata
➔ DFU
33
Kconfig
include/config.mk .config
include/config.h
$ make $ make
tools/scripts/define2mk.sed scripts/kconfig/conf
include/autoconf.mk include/autoconf.mk
include/autoconf.mk.dep include/autoconf.mk.dep
include/spl-autoconf.mk include/spl/autoconf.mk
include/tpl-autoconf.mk include/tpl/autoconf.mk
34
FDT (Flat Device Tree)
35
FDT, u-boot
/* arch/arm/dts/imx6qdl-u-boot.dtsi */
/ {
soc {
u-boot,dm-spl;
aips-bus@02000000 {
u-boot,dm-spl;
};
};
};
&gpio1 {
u-boot,dm-spl;
};
36
FDT, libfdt
e amount
py l a r g
pdat e, co
? add/u
e d t o rebuilt
?t ree ne
i ng is slow
a ve r s
? tree tr
37
Livetree (Live Device Tree)
/* old code */
plat->regs = (struct zynq_spi_regs *)devfdt_get_addr(bus);
plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
250000000);
/* new code */
plat->regs = (struct zynq_spi_regs *)dev_read_addr(bus);
plat->frequency = dev_read_u32_default(bus, "spi-max-frequency", 250000000);
return 0;
}
38
FDT Overlay
39
/dts-v1/;
/ {
images {
kernel {
data = /incbin/("./zImage");
type = "kernel";
load = <0x10080000>;
entry = <0x10080000>;
};
fdt-1 {
data = /incbin/("./imx6q-icore.dtb");
type = "flat_dt";
};
fdt-2 {
data = /incbin/("./imx6q-icore-mipi.dtb");
type = "flat_dt";
};
configurations {
default = "imx6q-icore.dtb";
imx6q-icore.dtb {
kernel = "kernel";
fdt = "fdt-1";
};
imx6q-icore-mipi.dtb {
kernel = "kernel";
fdt = "fdt-2";
};
};
};
};
40
FDT Overlay, loading
/* via FIT */
=> bootm $loadaddr#imx6q-icore.dtb#imx6q-icore-mipi
/* Manual load */
=> setenv fdt_addr 0x18000000
=> setenv fdt_ovaddr 0x180c0000
41
U-Boot Driver model
➔ Driver model
➔ DM, CPU
➔ DM, Power
➔ DM, Core
➔ DM, Peripherals
➔ Block layer
➔ USB layer
42
Driver model
consumer
s call
ect fu nction
d e l, dir
oc m o driver
? ad-h n ’t fit sam
e
c a
l e c o n trollers Uclass
p
? multi o m aintain
l t t
a l ab l e , difficu
c
? not s
Driver
Simple, scalable, m
odular, homogeneo
us
Lazy initialization,
but bounded Device
Small overhead, SP
L
Hardware
43
=> dm tree
Class index Probed Driver Name
-----------------------------------------
root 0 [ + ] root_drive root_driver
clk 0 [ ] fixed_rate |-- oscillator
mmc 0 [ + ] rockchip_r |-- dwmmc@ff0c0000
blk 0 [ + ] mmc_blk | `-- dwmmc@ff0c0000.blk
mmc 1 [ + ] rockchip_r |-- dwmmc@ff0f0000
blk 1 [ ] mmc_blk | `-- dwmmc@ff0f0000.blk
serial 0 [ + ] ns16550_se |-- serial@ff690000
eth 0 [ ] gmac_rockc |-- ethernet@ff290000
usb 0 [ ] dwc2_usb |-- usb@ff540000
usb 1 [ ] dwc2_usb |-- usb@ff580000
ram 0 [ ] rockchip_r |-- dmc@ff610000
i2c 0 [ + ] i2c_rockch |-- i2c@ff650000
pmic 0 [ + ] rk8xx pmic | `-- pmic@1b
regulator 0 [ ] rk8xx_buck | |-- DCDC_REG1
regulator 1 [ ] rk8xx_buck | |-- DCDC_REG2
regulator 2 [ ] rk8xx_buck | |-- DCDC_REG3
regulator 3 [ ] rk8xx_buck | |-- DCDC_REG4
regulator 4 [ ] rk8xx_ldo | |-- LDO_REG1
44
Driver model
consumer
Uclass
Driver
Device
Hardware
45
DM, CPU
46
DM, Power
47
DM, Core
48
DM, Peripherals
49
UCLASS_DRIVER(spi) = {
.id = UCLASS_SPI,
.name = "spi",
.flags = DM_UC_FLAG_SEQ_ALIAS,
.post_bind = dm_scan_fdt_dev,
.post_probe = spi_post_probe,
.child_pre_probe = spi_child_pre_probe,
.per_device_auto_alloc_size = sizeof(struct dm_spi_bus),
.per_child_auto_alloc_size = sizeof(struct spi_slave),
.per_child_platdata_auto_alloc_size = sizeof(struct dm_spi_slave_platdata),
.child_post_bind = spi_child_post_bind,
};
U_BOOT_DRIVER(zynq_qspi) = {
.name = "zynq_qspi",
.id = UCLASS_SPI,
.of_match = zynq_qspi_ids,
.ops = &zynq_qspi_ops,
.ofdata_to_platdata = zynq_qspi_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct zynq_qspi_platdata),
.priv_auto_alloc_size = sizeof(struct zynq_qspi_priv),
.probe = zynq_qspi_probe,
};
50
static int sun4i_usb_phy_exit(struct phy *phy)
{
clk_disable(&usb_phy->clocks);
reset_assert(&usb_phy->resets);
}
static int sun4i_usb_phy_init(struct phy *phy)
{
clk_enable(&usb_phy->clocks);
reset_deassert(&usb_phy->resets);
}
static struct phy_ops sun4i_usb_phy_ops = {
.init = sun4i_usb_phy_init,
.exit = sun4i_usb_phy_exit,
};
static int sun4i_usb_phy_probe(struct udevice *dev)
{
clk_get_by_name(dev, "usb0_phy", &phy->clocks);
reset_get_by_name(dev, "usb0_reset", &phy->resets);
}
U_BOOT_DRIVER(sun4i_usb_phy) = {
.id = UCLASS_PHY,
.ops = &sun4i_usb_phy_ops,
.probe = sun4i_usb_phy_probe,
}; 51
Generic Block Layer
blk_common_cmd
cmd/blk_common.c
blk_read_devnum blk_write_devnum
BLK Core
52
USB framework
➔ via UCLASS_USB
➔ uclass core: drivers/usb/host/usb-uclass.c
➔ platform specific uboot driver: drivers/usb/host/ehci-generic.c
➔ USB control, bulk, interrupt, create_int_queue etc via dm_usb_ops
➔ include/usb.h
➔ cmd/usb.c
➔ USB Gadgets can probe via Gadget UCLASS
➔ drivers/usb/gadget/ether.c, USB ETH Gadget
➔ MUSB can operate Host and Peripheral
➔ MUSB Host access via UCLASS_USB
➔ MUSB Peripheral access via
◆ UCLASS_USB_DEV_GENERIC - host devices
◆ UCLASS_USB_GADGET_GENERIC - gadget devices
➔ drivers/usb/musb-new/sunxi.c, SunXi MUSB driver
53
OF Platdata
#include <dm/platform_data/spi_davinci.h>
U_BOOT_DEVICE(davinci_spi) = {
.name = "davinci_spi",
.platdata = &davinci_spi_data,
};
54
Firmware Upgrade
f_fastboot
mmc nand ram sf
f_mass_storage
55
Port new hardware
➔ Prerequisite
➔ Vyasa RK3288 port
56
Prerequisite
57
Vyasa RK3288 port
➔ 3 stage bootloader
➔ TPL
◆ CPU, dram init, clocks, debug uart
◆ SPL BOOTROM
➔ SPL
◆ SPL_OF_CONTROL, UART, falcon
◆ SPL MMC
➔ U-Boot proper
◆ OF_CONTROL, UART, MMC, I2C,
◆ CLK, Reset, commands etc
58
➔ Add SoC support
◆ arch/arm/mach-rockchip
◆ arch/arm/mach-rockchip/rk3288
◆ CPU clock, syscon, linker script etc
◆ Add TARGET_VYASA_RK3288 in arch/arm/mach-rockchip/rk3288/Kconfig
➔ Add DTS support
◆ arch/arm/dts/rk3288-vyasa.dts
◆ arch/arm/dts/rk3288-vyasa-u-boot.dtsi
➔ Add Board support
◆ board/amarula/vyasa-rk3288/
◆ Board specific code
◆ Board specific SPL code, if require
◆ board/amarula/vyasa-rk3288/MAINTAINERS
➔ Add header file
◆ include/configs/vyasa-rk3288.h
◆ Include common useful headers
◆ Distro CONFIG_ definitions
◆ CONFIG_ items which doesn’t support Kconfig yet
➔ Add defconfig file
◆ CONFIG_ items which support Kconfig
➔ Finally run buildman or travis to make sure all build fine
➔ And use patman for sending patches to Mainline
ELCE 2017: Porting U-Boot and Linux on new ARM boards:a step-by-step guide, Quentin Schulz
59
U-Boot TPL 2018.09-00097-gd1e15041abf3 (Sep 13 2018 - 15:37:34 +0530)
Trying to boot from BOOTROM
Returning to boot ROM...
In: serial
Out: serial
Err: serial
Model: Amarula Vyasa-RK3288
Net: eth0: ethernet@ff290000
Hit any key to stop autoboot: 0
switch to partitions #0, OK
=>
60
Future plan
➔ Kconfig migration
➔ Driver model migrations
◆ BLK, DM_MMC, DM_SCSI, DM_USB
◆ DM_SPI, DM_SPI_FLASH, DM_VIDEO, DM_PCI
➔ MTD driver model
➔ Architecture CLK, RESET, Pinctrl Subsystems
61
Conclusion
62
Questions??
Thank you
Jagan Teki <jagan@amarulasolutions.com>
63