linux u-boot 开发指南 1 前言 1.1 编写目的 介绍 u-boot 的编译打包、基本配置、常用命令的使用、基本调试方法等, 为 u-boot 的移植及应用开发提供了基础。
1.2 适用范围 本文档适用于 brandy2.0, 即 u-boot-2018 平台。
1.3 相关人员 u-boot 开发/维护人员,内核开发人员。
2 lichee 类宏关键字解释 请到 longan 目录下的.buildconfig 查看目前使用了以下 lichee 类宏。
lichee_ic ——> ic名
lichee_chip ——> 平台名
lichee_board ——> 板级名
lichee_arch ——> 所属架构
lichee_board_config_dir ——> 板级目录
lichee_brandy_out_dir ——> bin文件所在目录
lichee_plat_out ——> 平台临时bin所在目录
lichee_chip_config_dir ——> ic目录
3 编译方法介绍 3.1 准备编译工具链 准备编译工具链接执行步骤如下:
1)cd longan/brandy/brandy-2.0/
2)./build.sh -t
3.2 快速编译 boot0 及 u-boot 在longan/brandy/brandy-2.0/目录下,执行 ./build.sh -p 平台名称,可以快速完成整个 boot 编译动作。这个平台名称是指,lichee_chip。
./build.sh -p {lichee_chip} //快速编译spl/u-boot
./build.sh -o spl-pub -p {lichee_chip} //快速编译spl-pub
./build.sh -o uboot -p {lichee_chip} //快速编译u-boot
3.3 编译 u-boot cd longan/brandy/brandy-2.0/u-boot-2018/进入 u-boot-2018 目录。以{lichee_chip}为例,依次执行如下操作即可。
1)make {lichee_chip}_defconfig
2)make -j
3.4 编译 boot0/fes/sboot cd longan/brandy/brandy-2.0/spl-pub进入spl-pub目录,需设置平台和要编译的模块参数。以{lichee_chip}为例,编译 nand/emmc 的方法如下:
编译boot0
make distclean
make p={lichee_chip} m=nand
make boot0
make distclean
make p={lichee_chip} m=emmc
make boot0
编译fes
make distclean
make p={lichee_chip} m=fes
make fes
编译sboot
make distclean
make p={lichee_chip} m=sboot
make sboot
4 u-boot 功能及其配置方法/文件介绍 4.1 u-boot 功能介绍 在嵌入式操作系统中,bootloader/u-boot 是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在 sunxi 平台中,除了必须的引导系统启动功能外,boot 系统还提供烧写、升级等其它功能。
u-boot 主要功能可以分为以下几类
引导内核
能从存储介质(nand/mmc/spinor)上加载内核镜像到 dram 指定位置并运行。
量产 & 升级
包括卡量产,usb 量产,私有数据烧录,固件升级
开机提示信息
开机能显示启动 logo 图片(bmp 格式)
fastboot 功能
实现 fastboot 的标准命令,能使用 fastboot 刷机
4.2 u-boot 功能配置方法介绍 u-boot 中的各项功能可以通过 defconfig 或配置菜单 menuconfig 进行开启或关闭, 具体配置
方法如下:
4.2.1 通过 defconfig 方式配置 vim /longan/brandy/brandy-2.0/u-boot-2018/configs/{lichee_chip}_defconfig
开{lichee_chip}defconfig或{lichee_chip}nor_defconfig后,在相应的宏定义前去掉或添加#即可将相应功能开启或关闭。如下图,只要将config_sunxi_nand前的#去掉即可支持 nand 相关功能,其他宏定义的开启关闭也类似。修改后需要运行make xxx_defconfig使修改后的配置生效。
图 4-1: defconfig 配置图
4.2.2 通过 menuconfig 方式配置 通过 menuconfig 方式配置的方法步骤如下:
cd brandy/brandy-2.0/u-boot-2018/
执行make menuconfig命令,会弹出 menuconfig 配置菜单窗口,如下图所示。此时即可对各模块功能进行配置,配置方法 menuconfig 配置菜单窗口中有说明。
修改后配置已经生效,直接 make 即可生成对应 bin。如果重新运行make xxx_defconfig,通过menuconfig 方式修改的配置会在运行make xxx_defconfig后被xxx_defconfig中的配置覆盖。
图 4-2: menuconfig 配置菜单图
4.3 u-boot 配置参数文件介绍 u-boot 自 linux-5.4 以后不再使用 sysconfig 和内核 dts 作为配置文件,而是使用 u-boot 自带的 dts 来配置参数。kernel-dts 与 u-boot-dts 完全独立。
4.3.1 u-boot-dts 路径 u-boot-dts 路径为:vim longan/brandy/brandy-2.0/u-boot-2018/arch/arm/dts
4.3.2 u-boot-dts,defconfig 配置 配置项 配置项含义
config_of_separate 构建 u-boot 设备树成为 u-boot 的一部分
config_of_board 关闭使用外部 dts
config_default_device_tree 选择构建的 dts 文件文件名
config_sunxi_necessary_replace_fdt 开启选项, 实现内部 dts 换成外部 dts
配置项 选项
config_of_separate y
config_of_board n
config_default_device_tree “{lichee_chip}-soc-system”
config_sunxi_necessary_replace_fdt y
4.3.3 u-boot-dts 注意事项 4.3.3.1 编译注意事项
1.dts 分为板级 dts,和系统 dts。
系统 dts 由 config_default_device_tree 决定,可以在 $(config_sys_config_name)_defconfig找到该宏的定义。
系统 dts 最终会 include 板级 dts,文件路径 {lichee_board_config_dir},文件名:uboot-board.dts。
我们可以通过编译时的打印判断启动的 dts
objcopy examples/standalone/hello_world.srec
objcopy examples/standalone/hello_world.bin
ld u-boot
objcopy u-boot.srec
objcopy u-boot-nodtb.bin
‘{lichee_board_config_dir}/uboot-board.dts’ -> ‘~/longan/brandy/brandy-2.0/u-boot-2018/
arch/{lichee_arch}/dts/.board-uboot.dts’
dtc arch/{lichee_arch}/dts/{lichee_chip}-soc-system.dtb
sym u-boot.sym
shipped dts/dt.dtb
fdtgrep dts/dt-spl.dtb
copy u-boot.dtb
cat u-boot-dtb.bin
copy u-boot.bin
‘u-boot.bin’ -> ‘{lichee_chip}.bin’ ‘u-boot-g{lichee_chip}.bin’ -> ‘{lichee_brandy_out_dir}/bin/u-boot-g{lichee_chip}.bin’ ‘u-boot-g{lichee_chip}.bin’ -> ‘{lichee_plat_out}/u-boot-g{lichee_chip}.bin’
cfgchk u-boot.cfg
4.3.3.2 语法注意事项
当系统 dts 与板级 dts 存在同路径下同名节点时,板级 dts 将会覆盖系统 dts。
4.3.3.3 运行时注意事项
为了在启动内核前更新参数到内核 dts 和可以在 u-boot 控制台查看修改 dts。按阶段划分可以分为使用内部 dts 阶段和使用内核 dts 阶段,如下图所示。
图 4-3: dts 变化图
可以通过命令set_working_fdt来切换当前生效的 fdt。
[04.562]update bootcmd [04.576]change working_fdt 0x7bebee58 to 0x7be8ee58 [04.587]update dts hit any key to stop autoboot: 0 => set set_working_fdt setenv setexpr => set_working_fdt 0x7bebee58 change working_fdt 0x7be8ee58 to 0x7bebee58 =>
5 u-boot 常用命令介绍 5.1 env 命令说明 通过env命令可以对{lichee_chip_config_dir}/configs/default/env.cfg中的环境变量进行查看及更改。在小机启动过程中按任意键进入 u-boot shell 命令状态,输入命令env即可查看命令帮助信息。
具体示例如下:
输入命令env print,可查看当前所有的环境变量信息,如下:
=> pri ab_partition_list=bootloader,env,boot,vendor_boot,dtbo,vbmeta,vbmeta_system,vbmeta_vendor android_trust_chain=true boot_fastboot=fastboot boot_normal=sunxi_flash read 45000000 boot;bootm 45000000 boot_recovery=sunxi_flash read 45000000 recovery;bootm 45000000 bootcmd=run setargs_mmc boot_normal bootdelay=0 bootreason=charger bt_mac=20:a1:11:12:13:44 cma=8m console=ttyas0,115200 earlyprintk=sunxi-uart,0x05000000 fdtcontroladdr=7bed0e60 fileaddr=40000000 filesize=15cf6 force_normal_boot=1 init=/init initcall_debug=0 keybox_list=widevine,ec_key,ec_cert1,ec_cert2,ec_cert3,rsa_key,rsa_cert1,rsa_cert2,rsa_cert3 loglevel=8 mac=10:14:15:15:9a:ca mmc_root=/dev/mmcblk0p4 nand_root=/dev/nand0p4 partitions=bootloader_a@mmcblk0p1:bootloader_b@mmcblk0p2:env_a@mmcblk0p3:env_b@mmcblk0p4: boot_a@mmcblk0p5:boot_b@mmcblk0p6:vendor_boot_a@mmcblk0p7:vendor_boot_b@mmcblk0p8: super@mmcblk0p9:misc@mmcblk0p10:vbmeta_a@mmcblk0p11:vbmeta_b@mmcblk0p12: vbmeta_system_a@mmcblk0p13:vbmeta_system_b@mmcblk0p14:vbmeta_vendor_a@mmcblk0p15: vbmeta_vendor_b@mmcblk0p16:frp@mmcblk0p17:empty@mmcblk0p18:metadata@mmcblk0p19: private@mmcblk0p20:dtbo_a@mmcblk0p21:dtbo_b@mmcblk0p22:media_data@mmcblk0p23: udisk@mmcblk0p24 rotpk_status=0 setargs_mmc=setenv bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${ initcall_debug} console=${console} loglevel=${loglevel} root=${mmc_root} init=${init} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 androidboot.force_normal_boot=${force_normal_boot} androidboot.slot_suffix=${slot_suffix} setargs_nand=setenv bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${ initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} init=${init} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 androidboot.force_normal_boot=${force_normal_boot} androidboot.slot_suffix=${slot_suffix} slot_suffix=_a snum=a100b3n041 wifi_mac=10:a1:11:12:13:44 environment size: 2078/131068 bytes =>
输入命令env set bootdelay 3,可更改环境变量bootdelay(即 boot 启动时 log 中的倒计时延迟时间)值的大小。
输入命令env save,即可将上述更改进行保存,保存后重新上电,或输入命令reset,即可看到上述更改bootdelay的延时时间被更改生效。
其他env命令请查看env帮助信息。
5.2 sunxi_flash read 命令说明 5.2.1 使用方法 用以下命令将 flash 指定地址中数据读到 dram 的指定地址处:
sunxi_flash read dram_addr flash_addr
5.2.2 使用示例 sunxi_flash read 0x45000000 env—将env分区数据读到dram的0x45000000地址处 sunxi_flash read 45000000 boot;bootm 45000000—将flash中boot分区数据读到dram的0x45000000地 址,并 从0x45000000处启动。
5.3 fastboot 命令说明 fastboot 是 android 平台上一个通用的刷机工具,也是一个很好的开发调试工具,以下介绍 fastboot 的基本使用方法。
5.3.1 使用前提 fastboot pc 端工具可以从 google android sdk(android-sdk-windows/tools) 中获得,也可以在 android 源代码编译过后的生成文件获得 (out/host/linux-x86/bin)。
在 linux 系统中,使用 fastboot 不需要安装驱动。但在 windows 系统中,使用 fastboot 前需安装 fastboot 相关驱动。adb 的驱动在 fastboot 模式下也可以安装成功,但是无法使用,请使用我们提供的驱动,并手动安装。
5.3.2 使用步骤 小机上电启动,按任意键进入 u-boot 命令状态;
串口端输入fastboot命令;
打开 pc 端 fastboot 工具,并输入fastboot devices命令,看是否有 fastboot 设备显示;
在正确获取 fastboot 设备的前提下,输入命令fastboot flash env /path/to/env.fex,将env.fex写到env分区(/path/to/目录下的env.fex中bootdelay值应该与 flash 中原有env中bootdelay值不同,这样可根据bootdelay值不同来确定 fastboot 烧写是否成功), 同下载env.fex分区一样, 输入命令“fastboot flash boot /path/to/boot.img”将内核下载到内存中;
输入fastboot reboot命令重启,查看启动倒计时即bootdelay的值是否改变;
5.3.3 fastboot 基本命令使用示例 fastboot 几个基本命令示例如下:
fastboot devices :显示 fastboot 的设备。
fastboot erase :擦除分区,例如fastboot erase boot,擦除boot分区。
fastboot flash:旧分区(待写分区),例如fastboot flash boot/path/to/boot.img,将boot.img写到boot分区。
注意事项:
fastboot 中使用的分区和sys_partition.fex中分区一致,具体的分区信息可以从小机上电启动进入 u-boot shell 命令状态,输入命令part list sunxi_flash 0中获取,分区信息如下:
=> part list sunxi_flash 0 partition map for unknown device 0 -- partition type: efi part start lba end lba name attributes type guid partition guid 1 0x00008000 0x00017fff bootloader attrs: 0x8000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 guid: a0085546-4166-744a-a353-fca9272b8e45 2 0x00018000 0x0001ffff env attrs: 0x8000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 guid: a0085546-4166-744a-a353-fca9272b8e46 3 0x00020000 0x0002ffff boot attrs: 0x8000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 guid: a0085546-4166-744a-a353-fca9272b8e47 4 0x00030000 0x0032ffff super attrs: 0x8000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 guid: a0085546-4166-744a-a353-fca9272b8e48 5 0x00330000 0x00337fff misc attrs: 0x8000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 guid: a0085546-4166-744a-a353-fca9272b8e49 6 0x00338000 0x00347fff recovery attrs: 0x8000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 guid: a0085546-4166-744a-a353-fca9272b8e4a
5.4 fat 命令说明 fat命令可以对 fat 文件系统的相关存储设备进行查询及文件读写操作,在打包固件的时候, 我们会制作启动资源分区镜像, 把指定的目录下的文件按照文件系统的格式排布,文件中包括了原来目录中的所有文件,并完全按照目录结构排列。当把这个镜像文件烧写到存储设备上的某一个分区的时候,可以看到这个分区和原有目录的内容一样。使用fat可以方便地以文件和目录的方式对小机 flash 进行数据访问,如显示 logo。这些指令基本上要和 u 盘或者 sd 卡同时使用,主要用于读取这些移动存储器上的 fat 分区。其相关操作命令如下:
fatls : 列出相应设备目录上的所有文件,示例如下图:
图 5-1: fatls 命令执行示例图
说明
补充说明,fatls mmc 2:2 中的第一个 2 表示的是 emmc 设备,2 表示其分区号,其说明如下图:
图 5-2: fatls 命令参数说明图
fatinfo: 打印出相应设备目录的文件系统信息,示例如下图:
图 5-3: fatinfo 命令执行示例图
fatload: 从 fat 文件系统中读取二进制文件到 ram 存储中,示例如下:
sunxi#usb start (re)start usb... usb0: start sunxi ehci1... config usb pin success config usb clk ok sunxi ehci1 init ok... usb ehci 1.00 scanning bus 0 for devices... 3 usb device(s) found scanning usb for storage devices... 1 storage device(s) found sunxi#fatls usb 0:1 / 16024600 sandisksecureaccessv3_win.exe sandisk secureaccess/ lost.dir/ android/ test/ video test/ amapauto/ 0 vid_20161017_160818.ts phoenixsuit/ system volume information/ 0 vid_20161017_160919.ts video/ 156672 wifi pro_com su.exe 495 sys.ini 1035 pr_80211g_all.ini config/ 158208 wifi pro_new.exe 158208 wifi pro.exe 0 vid_20161017_164822.ts 0 vid_20161017_164906.ts sunxi-tvd/ 71149 sys_config.fex vga/ 397836884 system.img 14180352 boot.img 13 file(s), 13 dir(s) sunxi#fatload usb 0:1 0x42000000 boot.img reading boot.img 14180352 bytes read in 1149 ms (11.8 mib/s) sunxi#mmc dev 2 mmc2(part 0) is current device sunxi#mmc write 0x42000000 0x15000 5000 mmc write: dev # 2, block # 86016, count 20480 ... 20480 blocks written: ok
说明:以上操作即将 u 盘的boot.img写到对应的 mmc 分区地址处。
fatwrite: 从内存中将对应的文件写到设备文件系统中。
5.5 md 命令说明 md命令可以对指定内存的数据进行查看,方便了解内存的数据情况及调试工作。其使用方法如下:
md 0xf0000000: 即用md命令查看内存dram 0xf0000000处内容
5.6 fdt 命令说明 fdt:flattened device tree 的缩写在 u-boot 控制台停下后,输入fdt,可以查看fdt命令帮助。
sunxi#fdt fdt - flattened device tree utility commands usage: fdt addr [-c] [] - set the [control] fdt location to fdt move - copy the fdt to and make it active fdt resize - resize fdt to size + padding to 4k addr fdt print [] - recursive print starting at fdt list [] - print one level starting at fdt get value - get and store in fdt get name - get name of node and store in fdt get addr - get start address of and store in fdt get size [] - get size of [] or num nodes and store in fdt set [] - set [to ] fdt mknode - create a new node after fdt rm [] - delete the node or fdt header fdt bootcpu - set boot cpuid fdt memory - add/update memory node fdt rsvmem print - show current mem reserves fdt rsvmem add - add a mem reserve fdt rsvmem delete - delete a mem reserves fdt chosen [] - add/update the /chosen branch in the tree / - initrd start/end addr note: dereference aliases by omiting the leading '/', e.g. fdt print ethernet0。 sunxi#
说明
其中常用的命令就是fdt list 和 fdt set,fdt list 用来查询节点配置,fdt set 用来修改节点配置。
5.6.1 查询配置 首先确定要查询的字段在 device tree 的路径,如果不知道路径,则需要用fdt命令按以下步骤进
行查询。1. 在根目录下查找。
sunxi#fdt list / / { model = {lichee_chip}; compatible = arm,{lichee_chip}, arm,{lichee_chip}; interrupt-parent = ; #address-cells = ; #size-cells = ; ...................... cpuscfg { }; ion { }; dram { }; memory@40000000 { }; interrupt-controller@1c81000 { }; sunxi-chipid@1c14200 { }; timer { }; pmu { }; dvfs_table { }; dramfreq { }; gpu@0x01c40000 { }; wlan { }; bt { }; btlpm { }; };
如果找到需要的配置,比如wlan的配置,运行如下命令即可。
sunxi#fdt list /wlan //注意路径中的 / wlan { compatible = allwinner,sunxi-wlan; clocks = ; wlan_power = vcc-wifi; wlan_io_regulator = vcc-wifi-io; wlan_busnum = ; status = okay; device_type = wlan; wlan_regon = ; wlan_hostwake = ; };
在 soc目录下找。如果在第一步中没有发现要找的配置,比如nand0的配置,则该配置可能在soc目录下。
sunxi#fdt list /soc soc@01c00000 { compatible = simple-bus; #address-cells = ; #size-cells = ; ranges; device_type = soc; ...................... hdmi@01ee0000 { }; tr@01000000 { }; pwm@01c21400 { }; nand0@01c03000 { }; thermal_sensor { }; cpu_budget_cool { }; ....................... };
然后用如下命令显示即可:
sunxi#fdt list /soc/nand0 nand0@01c03000 { compatible = allwinner,sun50i-nand; device_type = nand0; reg = ; interrupts = ; clocks = ; pinctrl-names = default, sleep; pinctrl-1 = ; nand0_regulator1 = vcc-nand; nand0_regulator2 = none; nand0_cache_level = ; nand0_flush_cache_num = ; nand0_capacity_level = ; nand0_id_number_ctl = ; nand0_print_level = ; nand0_p0 = ; nand0_p1 = ; nand0_p2 = ; nand0_p3 = ; status = disabled; nand0_support_2ch = ; pinctrl-0 = ; };
使用路径别名查找。别名是 device tree 中完整路径的一个简写,有一个专门的节点 ( /aliases) 来表示别名的相关信息,用如下命令可以查看系统中别名的配置情况:
sunxi#fdt list /aliases aliases { serial0 = /soc@01c00000/uart@01c28000; .............. mmc0 = /soc@01c00000/sdmmc@01c0f000; mmc2 = /soc@01c00000/sdmmc@01c11000; nand0 = /soc@01c00000/nand0@01c03000; disp = /soc@01c00000/disp@01000000; lcd0 = /soc@01c00000/lcd0@01c0c000; hdmi = /soc@01c00000/hdmi@01ee0000; pwm = /soc@01c00000/pwm@01c21400; boot_disp = /soc@01c00000/boot_disp; }; sunxi#
由于配置了nand0节点的路径别名,因此可以用如下命令来显示nand0的配置信息。
sunxi#fdt list nand0 nand0@01c03000 { compatible = allwinner,sun50i-nand; device_type = nand0; reg = ; .................. pinctrl-names = default, sleep; pinctrl-1 = ; };
注:在fdt的所有命令中,alias 可以用作path参数。
fdt list [] - print one level starting at fdt set [] - set [to ]
5.6.2 修改配置 5.6.2.1 修改整数配置
命令格式:fdt set path prop 示例:fdt set /wlan wlan_busnum
sunxi#fdt list /wlan wlan { compatible = allwinner,sunxi-wlan; clocks = ; wlan_power = vcc-wifi; wlan_io_regulator = vcc-wifi-io; wlan_busnum = ; status = disable; device_type = wlan; }; sunxi#fdt set /wlan wlan_busnum sunxi#fdt list /wlan wlan { compatible = allwinner,sunxi-wlan; clocks = ; wlan_power = vcc-wifi; wlan_io_regulator = vcc-wifi-io; wlan_busnum = ; //修改后 status = disable; device_type = wlan; };
注:修改整数时,根据需要也可配置为数组形式,需要用空格来分隔。命令格式:fdt set path prop
5.6.2.2 修改字符串配置
命令格式:fdt set path prop xxxxx 示例:fdt set /wlan status disable
sunxi#fdt list /wlan wlan { compatible = allwinner,sunxi-wlan; clocks = ; wlan_power = vcc-wifi; wlan_io_regulator = vcc-wifi-io; wlan_busnum = ; status = okay; device_type = wlan; }; sunxi#fdt set /wlan status disable sunxi#fdt list /wlan wlan { compatible = allwinner,sunxi-wlan; clocks = ; wlan_power = vcc-wifi; wlan_io_regulator = vcc-wifi-io; wlan_busnum = ; status = disable; //修改后 device_type = wlan; }; sunxi#
注:修改字符串时,根据需要也可配置为数组形式,需要用空格来分隔。命令格式:fdt set path prop string1 string2
5.6.3 gpio 或者 pin 配置特殊说明 接口对应的数字编号说明如下:
#define pa 0 #define pb 1 #define pc 2 #define pd 3 #define pe 4 #define pf 5 #define pg 6 #define ph 7 #define pi 8 #define pj 9 #define pk 10 #define pl 11 #define pm 12 #define pn 13 #define po 14 #define pp 15 #define default 0xffffffff
sysconfig 中描述 gpio 的形式如下:port:端口+组内序号
5.6.3.1 pin 配置说明
pinctrl 节点分为 cpux 和 cpus,对应的节点路径如下:cpux : /soc/pinctrl@01c20800 cpus:/soc/pinctrl@01f02c00
5.6.3.2 查看 pin 配置
pin 配置属性字段说明:
属性字段 含义
allwinner,function 对应于 sysconfig 中的主键名
allwinner,pins 对应于 sysconfig 中每个 gpio 配置中的端口名
allwinner,pname 对应于 sysconfig 中主键下面子键名字
allwinner,muxsel 功能分配
allwinner,pull 内部电阻状态
allwinner,drive 驱动能力
allwinner,data 输出电平状态
说明
其中0xffffffff表示使用默认值。
按以下方法查看cpux的 pin 配置。
sunxi#fdt list /soc/pinctrl@01c20800/lcd0 lcd0@0 { linux,phandle = ; phandle = ; allwinner,pins = pd12, pd13, pd14, pd15, pd16, pd17, pd18, pd19, pd20, pd21; allwinner,function = lcd0; allwinner,pname = lcdd0, lcdd1, lcdd2, lcdd3, lcdd4, lcdd5, lcdd6, lcdd7, lcdd8, lcdd9; allwinner,muxsel = ; allwinner,pull = ; allwinner,drive = ; allwinner,data = ; }; sunxi#
按以下方法查看cpus的 pin 配置。
sunxi# fdt list /soc/pinctrl@01f02c00/s_uart0 s_uart0@0 { linux,phandle = ; phandle = ; allwinner,pins = pl2, pl3; allwinner,function = s_uart0; allwinner,pname = s_uart0_tx, s_uart0_rx; allwinner,muxsel = ; allwinner,pull = ; allwinner,drive = ; allwinner,data = ; }; sunxi#
5.6.3.3 修改 pin 配置
使用fdt set命令可以修改 pin 中相关属性字段
sunxi#fdt set /soc/pinctrl@01c20800/lcd0 allwinner,drive sunxi#fdt list /soc/pinctrl@01c20800/lcd0 lcd0@0 { linux,phandle = ; phandle = ; allwinner,pins = pd12, pd13, pd14, pd15, pd16, pd17, pd18, pd19, pd20, pd21; allwinner,function = lcd0; allwinner,pname = lcdd0, lcdd1, lcdd2, lcdd3, lcdd4, lcdd5, lcdd6, lcdd7, lcdd8, lcdd9; allwinner,muxsel = ; allwinner,pull = ; allwinner,drive = ; allwinner,data = ; };
说明
示例中该处修改会影响allwinner,pins表示的所有端口的驱动能力配置,修改allwinner,muxsel, allwinner,pull,allwinner,data的值也会产生类似效果。
5.6.3.4 gpio 配置说明
device tree 中 gpio 对应关系,以 usb 中usb_id_gpio为例
sunxi#fdt list /soc/usbc0 usbc0@0 { test = ; device_type = usbc0; compatible = allwinner,sun50i-otg-manager; ........ usb_serial_unique = ; usb_serial_number = 20080411; rndis_wceis = ; status = okay; usb_id_gpio = ; };
对应于 device tree 中 usb_id_gpio = ,解释如下:
属性数值 含义
0x00000030 device tree 内部一个节点相关信息,这里可以略过
0x00000007 端口 ph, 即 #define ph 7
0x00000009 组内序号, 即 ph09
0x00000000 功能分配, 即将 ph09 配为输入
0x00000001 内部电阻状态, 即配为上拉
0xffffffff 驱动能力, 默认值
0xffffffff 输出电平, 默认值
如果需要修改 usb_id_gpio的配置,可按如下方式(示例修改了驱动能力,输出电平两项):
sunxi#fdt set /soc/usbc0 usb_id_gpio sunxi#fdt list usbc0@0 { test = ; device_type = usbc0; compatible = allwinner,sun50i-otg-manager; ........ usb_serial_unique = ; usb_serial_number = 20080411; rndis_wceis = ; status = okay; usb_id_gpio = ; //修改ok }; sunxi#
5.7 其他命令说明(boot, reset, efex)
boot : 启动内核
reset: 复位重启系统
efex: 进入烧录状态
说明
注:其他更多 u-boot 命令介绍,请进入 u-boot shell 命令状态后输入help进行了解。
6 基本调试方法介绍 debug 调试信息介绍如下:
debug_mode
debug_mode 可以控制 boot0 的打印等级,打开文件{lichee_board_config_dir}/sys_config.fex,在主键 [platform] 下添加子键debug_mode = 8即表示开启所有打印,debug_mode=0 表示关闭启动时 boot0 的打印 log,未显式配置 debug_mode 时,按 debug_mode=8 处理。目前常用的打印等级有 0(关闭所有打印)、1(只显示关键节点打印)、4(打印错误信息)、8(打印所有 log 信息)。
debug_mode 可以控制 u-boot 的打印等级,打开文件{lichee_board_config_dir}/b3/uboot-board.dts,在 platform 节点下添加子键debug_mode = 8即表示开启所有打印,debug_mode=0 表示关闭启动时 u-boot 的打印log, 未显式配置 debug_mode 时,按 debug_mode=8 处理。目前常用的打印等级有 0(关闭所有打印)、1(只显示关键节点打印)、4(打印错误信息)、8(打印所有 log 信息)。
usb_debug 在烧录或启动过程中,若遇到烧录失败或启动失败大致挂死在 usb 相关模块,但又不确定具体位置,这时可以打开usb_debug进行调试,开启usb_debug后有关 usb 相关的运行信息会被较详细打印出来。打开usb_debug的方式:打开usb_base.h文件,将其中的#definesunxi_usb_debug宏定义打开,打开后重新编译 u-boot 并打包烧录即可。
7 进入烧写的方法 开机时按住 fel 键
开机时打开串口按住键盘数字’2’
进入 u-boot 控制台输入efex
进入 android 控制台输入 reboot efex
8 常用接口函数 8.1 fdt 相关接口 const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp)
• 作用:检索指定属性的值
• 参数:
• fdt: 工作 flattened device tree
• nodeoffset: 待修改节点的偏移
• name: 待检索的属性名
• lenp: 检索属性值的长度(会被覆盖)或者为 null
• 返回:
• 非空(属性值的指针):成功
• null(lenp 为空):失败
• 失败代码(lenp 非空):失败
int fdt_set_node_status(void *fdt, int nodeoffset, enum fdt_status status, unsigned int error_code)
• 作用:设置节点状态
• 参数:
• fdt: 工作 flattened device tree
• nodeoffset: 待修改节点的偏移
• status:fdt_status_okay, fdt_status_disabled, fdt_status_fail, fdt_status_fail_error_code
• error_code:optional, only used if status is fdt_status_fail_error_code
• 返回:
• 0: 成功
• 非 0: 失败
int fdt_path_offset(const void *fdt, const char *path)
• 作用:通过全路径查找节点的偏移量
• 参数:
• fdt: 工作 fdt
• path: 全路径名称
• 返回:
• >=0(节点的偏移量): 成功
• <0: 失败代码
static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, uint32_t val)
• 作用:将属性值设置为一个 32 位整型数值,如果属性值不存在,则新建该属性
• 参数:
• fdt: 工作 flattened device tree
• nodeoffset: 待修改节点的偏移
• name: 待修改的属性名
• val:32 位目标值
• 返回:
• 0: 成功
• <0: 失败代码
static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, uint64_t val)
• 作用:与fdt_setprop_u32类似,将属性值设置为一个 64 位整型数值,如果属性值不存在,则新建该属性
• 参数:
• fdt: 工作 flattened device tree
• nodeoffset: 待修改节点的偏移
• name: 待修改的属性名
• val:64 位目标值
• 返回:
• 0: 成功
• <0: 失败代码
#define fdt_setprop_string(fdt, nodeoffset, name, str) fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
• 作用:将属性值设置为一个字符串,如果属性值不存在,则新建该属性
• 参数:
• fdt: 工作 flattened device tree
• nodeoffset: 待修改节点的偏移
• name: 待修改的属性名
• str: 目标值
• 返回:
• 0: 成功
• <0: 失败代码
注意:在sys_config.fex的配置中,节点的启用状态为 0 或 1。转换到 fdt 中对应的 status 属性为disable或okay。
int save_fdt_to_flash(void *fdt_buf, size_t fdt_size)
• 作用:保存修改到 flash
• 参数:
• fdt_buf: 当前工作 flattened device tree
• fdt_size: 当前工作 flattened device tree 的大小,可以通过fdt_totalsize(fdt_buf )获取
• 返回:
• 0: 成功
• <0: 失败
应用参考
u-boot 中 fdt 命令行的实现:cmd/fdt.c
8.2 env 相关接口函数 int env_set(const char *varname, const char *varvalue)
• 作用:将环境变量 varname 的值设置为 varvalue,重启失效
• 参数:
• varname: 待设置环境变量的名称
• varvalue: 将指定的环境变量修改为该值
• 返回:
• 0: 成功
• 非 0: 失败
char *env_get(const char *name)
• 作用:获取指定环境变量的值
• 参数:
• name: 变量名称
• 返回:
• null: 失败
• 非空(环境变量的值):成功
int env_save(void)
• 作用:保存环境变量,重启仍保存
• 参数: 无
• 返回:
• 0: 成功
• 非 0: 失败
应用参考
board/sunxi/sunxi_bootargs.c update_bootargs通过 cmdline 向 kernel 提供信息,主要是通过更新bootargs变量实现env_set(bootargs, cmdline)。
8.3 调用 u-boot 命令行 int run_command_list(const char *cmd, int len, int flag)
• 作用:执行 u-boot 命令行
• 参数:
• cmd: 命令字符指针
• len: 命令行长度,设置为-1 则自动获取
• flag: 任意,因为 sunxi 中没有用到
• 返回:
• 0: 成功
• 非 0: 失败
应用参考:
common/autoboot.c autoboot_command实现了 u-boot 的自动启动命令
s = env_get(bootcmd);
run_command_list(s, -1, 0)。
8.4 flash 的读写 int sunxi_flash_read(uint start_block, uint nblock, void *buffer)
• 作用:将指定起始位置start_block的nblock读取到buffer
• 参数:
• start_block: 起始地址
• nblock:block 个数
• buffer: 内存地址
• 返回:
• 0: 成功
• 非 0: 失败
int sunxi_flash_write(uint start_block, uint nblock, void *buffer)
• 作用:将buffer写入指定起始位置start_block的nblock中
• 参数:
• start_block: 起始地址
• nblock:block 个数
• buffer: 内存地址
• 返回:
• 0: 成功
• 非 0: 失败
int sunxi_sprite_read(uint start_block, uint nblock, void *buffer)
• 作用与sunxi_flash_read相似
int sunxi_sprite_write(uint start_block, uint nblock, void *buffer)
• 作用与sunxi_flash_write相似
应用参考
common/sunxi/board_helper.c sunxi_set_bootcmd_from_mis实现了对 misc 分区的读写操作
8.5 获取分区信息 int sunxi_partition_get_partno_byname(const char *part_name)
• 作用:根据分区名称获取分区号
• 参数:
• part_name: 分区名称
• 返回:
• 0(分区号):成功
int sunxi_partition_get_info_byname(const char *part_name, uint *part_offset, uint *part_size)
• 作用:根据分区名称获取分区的偏移量和大小
• 参数:
• part_name: 分区名称
• part_offset: 分区的偏移量
• part_size: 分区的大小
• 返回:
• 0: 成功
• -1: 失败
uint sunxi_partition_get_offset_byname(const char *part_name)
• 作用:根据分区名称获取偏移量
• 参数:
• part_name: 分区名称
• 返回:
• 0 : 成功
int sunxi_partition_get_info(const char *part_name, disk_partition_t *info)
• 作用:根据part_name获取分区信息
• 参数:
• part_name: 分区名称
• info: 分区信息
• 返回:
• 非 0: 失败
• 0: 成功
lbaint_t sunxi_partition_get_offset(int part_index)
• 作用:card sprite 模式下获取分区的偏移量
• 参数:
• part_index: 分区号
• 返回:
• >=0(偏移量):成功
• -1: 失败
应用参考
启动时加载图片:drivers/video/sunxi/logo_display/sunxi_load_bmp.c
8.6 gpio 相关操作 int fdt_get_one_gpio(const char* node_path, const char* prop_name,user_gpio_set_t* gpio_list)
• 作用:根据路径node_path和 gpio 名称prop_name获取 gpio 配置
• 参数:
• node_path:fdt 路径
• prop_name:gpio 名称
• gpio_list:待获取的 gpio 信息
• 返回:
• 0:成功
• -1:失败
ulong sunxi_gpio_request(user_gpio_set_t *gpio_list, __u32 group_count_max)
• 作用:根据 gpio 配置获取 gpio 操作句柄
• 参数:
• gpio_list:gpio 配置列表,可以由fdt_get_one_gpio获得
• group_count_max: gpio_list中最大的 gpio 配置个数
• 返回:
• 0:失败
• >0(gpio 操作句柄):成功
__s32 gpio_write_one_pin_value(ulong p_handler, __u32 value_to_gpio, const char *gpio_name)
• 作用:根据 gpio 操作句柄写数据
• 参数:
• p_handler:gpio 操作句柄,可由sunxi_gpio_request获取
• value_to_gpio:待写入数据,0 或 1
• gpio_name:gpio 名称
• 返回:
• egpio_success:成功
• egpio_fail:失败
应用参考
操作 led 状态:
ssprite/sprite_led.c user_gpio_set_t gpio_init; fdt_get_one_gpio(/soc/card_boot, sprite_gpio0, &gpio_init); //获取/soc/card_boot中sprite_gpio0的gpio配置 sprite_led_hd = sunxi_gpio_request(&gpio_init, 1); //获取gpio操作句柄 gpio_write_one_pin_value(sprite_led_hd, sprite_led_status, sprite_gpio0); //操作led状态
9 常用资源的初始化阶段 • env :环境变量初始化后可以访问
• fdt :在 u-boot 运行开始即可访问
• malloc :在重定位后才能访问
全球首款L4级自动驾驶量产版轿车,计划于2021年正式交付用户
英特尔2024年Q1财测披露:营收预计在122亿至132亿美元之间
电池巨头启动IPO!
用于现场仪表和工厂自动化的创造性低功耗解决方案
万旭电业展示最新线材与天线产品
Linux U-Boot开发指南
高速PCB差分对路由以保持信号完整性
机器学习vsm算法
DARPA将为夜视镜带来颠覆性的变革
对飙三星S8, 小米MIX杀入韩国市场
液晶显示源程序代码
WIFI已经覆盖京沪高铁复兴号动车组 全部高铁覆盖指日可待
3D IC散热遭遇瓶颈 美国国防开发新型芯片制冷技术
黑芝麻智能华山二号A1000系列芯片进入量产阶段
摩托车防盗报警器原理电路图
调查统计机构Netmarketshare揭示了桌面操作系统使用的有趣趋势
从入门到旗舰:高通骁龙4/6/7/8系移动平台全解析
类似运满满APP开发
紫光展锐成为了全球手机芯片领域首家通过TMMi4级认证的企业
AMD 锐龙5000U/H系列与锐龙5000U/H系列性能对比