提供一种基于rkSDK buildroot使用dtbo的方法
简单说明:
- uboot中默认加载
default-dtb-overlay.dtbo
app/dtbo-tools/S03checkDTBO
开机检查拨码开关,并将/boot/overlays/default-dtb-overlay.dtbo
链接到目标dtbo,有效的dtbo名全部存放于dtbo_table
变量中
- build.sh中:新增dtbo编译选项,根据
RK_KERNEL_DTS_OVERLAYS
配置自动更新S03checkDTBO
中dtbo_table
变量,并将dtbo与S03checkDTBO
安装到rootfs
- 在.BoardConfig 添加
RK_KERNEL_DTS_OVERLAYS
环境变量
uboot补丁
| |
| |
| |
| |
| @@ -35,6 +35,7 @@ |
| #include <u-boot/sha1.h> |
| #include <u-boot/sha256.h> |
| #include <linux/usb/phy-rockchip-usb2.h> |
| +#include <mapmem.h> |
| |
| DECLARE_GLOBAL_DATA_PTR; |
| |
| @@ -552,6 +553,136 @@ static int rkimg_traverse_read_dtb(void *fdt, int where) |
| return -EINVAL; |
| } |
| |
| +static int do_get_ext2(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr) |
| +{ |
| + static char *fs_argv[5]; |
| + disk_partition_t part_info; |
| + char part_num[4]= {0}; |
| + |
| + int ret = part_get_info_by_name(dev_desc, "rootfs", &part_info); |
| + if (ret < 0){ |
| + printf("[warning] not found partion:%s\n","rootfs"); |
| + return ret; |
| + } |
| + |
| + sprintf(part_num, "%s:%d", env_get("devnum"), ret); |
| + |
| + fs_argv[0] = "ext2load"; |
| + fs_argv[1] = env_get("devtype"); |
| + fs_argv[2] = part_num; |
| + fs_argv[3] = file_addr; |
| + fs_argv[4] = (void *)file_path; |
| + |
| + printf("runcmd: <%s %s %s %s %s>\n",fs_argv[0],fs_argv[1],fs_argv[2],fs_argv[3],fs_argv[4]); |
| + |
| + if (!do_ext2load(cmdtp, 0, 5, fs_argv)) |
| + return 1; |
| + return -ENOENT; |
| +} |
| + |
| +static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const char *envaddr_name) |
| +{ |
| + unsigned long file_addr; |
| + char *envaddr; |
| + char addr_buf[18]; |
| + |
| + envaddr = env_get(envaddr_name); |
| + |
| + if (!envaddr){ |
| + printf("missing environment variable: %s\n", envaddr_name); |
| + return -ENOENT; |
| + } |
| + |
| + if (strict_strtoul(envaddr, 16, &file_addr) < 0) |
| + return -EINVAL; |
| + |
| + sprintf(addr_buf, "%lx", file_addr); |
| + |
| + return do_get_ext2(cmdtp, file_path, addr_buf); |
| +} |
| + |
| +static void kernel_fdt_overlay_apply( char *fdtoverlay) |
| +{ |
| + struct fdt_header *working_fdt; |
| + char *fdtoverlay_addr_env; |
| + ulong fdtoverlay_addr; |
| + ulong fdt_addr; |
| + int err; |
| + |
| + /* Get the main fdt and map it */ |
| + fdt_addr = simple_strtoul(env_get("fdt_addr_r"), NULL, 16); |
| + working_fdt = map_sysmem(fdt_addr, 0); |
| + err = fdt_check_header(working_fdt); |
| + if (err){ |
| + printf("Invalid fdt_addr_r for loading dtb\n"); |
| + return; |
| + } |
| + /* Get the specific overlay loading address */ |
| + env_set("fdtoverlay_addr_r","0x08000000"); |
| + fdtoverlay_addr_env = env_get("fdtoverlay_addr_r"); |
| + if (!fdtoverlay_addr_env) { |
| + printf("Invalid fdtoverlay_addr_r for loading overlays\n"); |
| + return; |
| + } |
| + |
| + fdtoverlay_addr = simple_strtoul(fdtoverlay_addr_env, NULL, 16); |
| + |
| + /* Cycle over the overlay files and apply them in order */ |
| + do { |
| + struct fdt_header *blob; |
| + char *overlayfile; |
| + char *end; |
| + int len; |
| + |
| + /* Drop leading spaces */ |
| + while (*fdtoverlay == ' ') |
| + ++fdtoverlay; |
| + |
| + /* Copy a single filename if multiple provided */ |
| + end = strstr(fdtoverlay, " "); |
| + if (end) { |
| + len = (int)(end - fdtoverlay); |
| + overlayfile = malloc(len + 1); |
| + strncpy(overlayfile, fdtoverlay, len); |
| + overlayfile[len] = '\0'; |
| + } else |
| + overlayfile = fdtoverlay; |
| + |
| + if (!strlen(overlayfile)) |
| + goto skip_overlay; |
| + |
| + /* Load overlay file */ |
| + err = get_relfile_envaddr(NULL, overlayfile, |
| + "fdtoverlay_addr_r"); |
| + if (err < 0) { |
| + printf("Failed loading overlay %s\n", overlayfile); |
| + goto skip_overlay; |
| + } |
| + |
| + /* Resize main fdt */ |
| + fdt_shrink_to_minimum(working_fdt, 8192); |
| + |
| + blob = map_sysmem(fdtoverlay_addr, 0); |
| + err = fdt_check_header(blob); |
| + if (err) { |
| + printf("Invalid overlay %s, skipping\n", |
| + overlayfile); |
| + goto skip_overlay; |
| + } |
| + |
| + err = fdt_overlay_apply_verbose(working_fdt, blob); |
| + if (err) { |
| + printf("Failed to apply overlay %s, skipping\n", |
| + overlayfile); |
| + goto skip_overlay; |
| + } |
| + |
| +skip_overlay: |
| + if (end) |
| + free(overlayfile); |
| + } while ((fdtoverlay = strstr(fdtoverlay, " "))); |
| +} |
| + |
| int rockchip_read_dtb_file(void *fdt) |
| { |
| int locate, ret; |
| @@ -584,7 +715,7 @@ int rockchip_read_dtb_file(void *fdt) |
| #if defined(CONFIG_ANDROID_BOOT_IMAGE) && defined(CONFIG_OF_LIBFDT_OVERLAY) |
| android_fdt_overlay_apply((void *)fdt); |
| #endif |
| - |
| + kernel_fdt_overlay_apply("/boot/overlays/default-dtb-overlay.dtbo"); |
| return 0; |
| } |
| #endif |
build.sh 补丁
| |
| +function build_kernel_dtbo(){ |
| + |
| + fs_overlay_dir="$TOP_DIR/buildroot/board/rockchip/rk356x/huaqi/fs-overlay" |
| + fs_dtbo_dir="$fs_overlay_dir/boot/overlays" |
| + kernel_dts_dir="$TOP_DIR/kernel/arch/arm64/boot/dts/rockchip" |
| + DTC="dtc-1.6.0" |
| + dtbo_tools="$TOP_DIR/app/dtbo-tools/S03checkDTBO" |
| + |
| + if [ -z "$RK_KERNEL_DTS_OVERLAYS" ];then |
| + echo "Don't set RK_KERNEL_DTS_OVERLAYS, exit ..." |
| + rm $fs_overlay_dir/etc/init.d/S03checkDTBO |
| + rm $fs_overlay_dir/boot -r |
| + return |
| + fi |
| + |
| + cd $kernel_dts_dir |
| + echo "cd $kernel_dts_dir" |
| + |
| + for dts in $RK_KERNEL_DTS_OVERLAYS |
| + do |
| + if [ -e "$dts.dts" ];then |
| + $DTC -I dts -O dtb $dts.dts -o $dts.dtbo |
| + if [ "$?" = "0" ];then |
| + echo "[DTC] $dts.dtbo" |
| + fi |
| + dtbo_table="$dtbo_table $dts.dtbo" |
| + else |
| + echo "[DTC] $dts.dtbo failed,no such file $dts.dts" |
| + fi |
| + done |
| + |
| + if [ -e "$fs_overlay_dir" ];then |
| + mkdir -p "$fs_dtbo_dir" |
| + fi |
| + |
| + echo "Install `ls *.dtbo` to $fs_dtbo_dir" |
| + |
| + |
| + cp $kernel_dts_dir/*.dtbo $fs_dtbo_dir |
| + |
| + if [ -e "$dtbo_tools" ];then |
| + sed "s/dtbo_table=/dtbo_table=($dtbo_table)/g" $dtbo_tools > $fs_overlay_dir/etc/init.d/S03checkDTBO |
| + echo "Install $dtbo_tools to $fs_overlay_dir/etc/init.d/S03checkDTBO" |
| + chmod +x $fs_overlay_dir/etc/init.d/S03checkDTBO |
| + cat $fs_overlay_dir/etc/init.d/S03checkDTBO | grep "dtbo_table=" |
| + else |
| + echo "[WARN]: Not found $dtbo_tools!!!" |
| + fi |
| + |
| + finish_build |
| +} |
| + |
| function build_kernel(){ |
| check_config RK_KERNEL_DTS RK_KERNEL_DEFCONFIG || return 0 |
| |
| @@ -670,8 +723,9 @@ function build_kernel(){ |
| fi |
| |
| build_check_power_domain |
| - |
| finish_build |
| + |
| + build_kernel_dtbo |
| } |
| |
| function build_modules(){ |
| @@ -1015,6 +1069,7 @@ function build_all(){ |
| check_security_condition |
| build_loader |
| build_kernel |
| + build_kernel_dtbo |
| build_toolchain |
| build_rootfs ${RK_ROOTFS_SYSTEM:-buildroot} |
| build_recovery |
| @@ -1272,6 +1327,7 @@ for option in ${OPTIONS}; do |
| uefi) build_uefi ;; |
| loader) build_loader ;; |
| kernel) build_kernel ;; |
| + dtbo) build_kernel_dtbo;; |
| modules) build_modules ;; |
| rootfs|buildroot|debian|yocto) build_rootfs $option ;; |
| pcba) build_pcba ;; |
| |
BoardConfig-rk3568-evb1-ddr4-v10.mk 中新增环境变量
| +export RK_KERNEL_DTS_OVERLAYS="rk3568-test rk3568-test2 rk3568-test3 rk3568-test4" |
在build.sh
中根据RK_KERNEL_DTS_OVERLAYS
配置自动更新dtbo_table
| #!/bin/sh |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| OverlaysPath="/boot/overlays" |
| OverlaysHeader="rk3568-huaqi-overlays" |
| dtbo_table= |
| EXE_NAME=$0 |
| switchGPIO="28 29 30" |
| |
| function log() |
| { |
| logger -s -t "[$EXE_NAME]" $@ |
| } |
| |
| function getSwichValue(){ |
| |
| for i in $switchGPIO |
| do |
| value="$value`gpioget -l 2 $i`" |
| done |
| |
| val_hex=$(printf "%02x" $((2#$value))) |
| echo "0x$val_hex" |
| } |
| |
| start() { |
| log "checkDTBO start ..." |
| if [ -d "$OverlaysPath" ];then |
| cd $OverlaysPath |
| else |
| log "Not found dir:$OverlaysPath,skip check device tree overlay!!!" |
| fi |
| |
| if [ -z "${dtbo_table[0]}" ];then |
| log "dtbo_table is empty,skip check device tree overlay!!!" |
| return |
| fi |
| |
| OLD_DTBO=`readlink default-dtb-overlay.dtbo` |
| |
| let swichValue="`getSwichValue`" |
| |
| if [ $swichValue -gt ${#dtbo_table[@]} ];then |
| log "dtbo_table[0-${#dtbo_table[@]}]:<${dtbo_table[@]}>" |
| log "Not define dtbo_table[$swichValue],exit..." |
| return |
| fi |
| |
| NEW_DTBO=${dtbo_table[$swichValue]} |
| |
| if [ ! -e "$NEW_DTBO" ];then |
| log "No such file:$NEW_DTBO" |
| log "skip set default-dtb-overlay.dtbo link to $NEW_DTBO!!!" |
| return |
| fi |
| |
| if [ "$OLD_DTBO" != "$NEW_DTBO" ];then |
| log "set default-dtb-overlay.dtbo link to $NEW_DTBO" |
| ln -sf $NEW_DTBO default-dtb-overlay.dtbo |
| sync |
| reboot |
| fi |
| } |
| |
| stop() { |
| echo "checkDTBO stop ..." |
| } |
| |
| restart() { |
| echo "checkDTBO restart ..." |
| stop |
| start |
| } |
| |
| case "$1" in |
| start|stop|restart) |
| "$1";; |
| reload) |
| |
| restart;; |
| *) |
| echo "Desc: Check device tree overlay plugin script" |
| echo "Usage: $0 {start|stop|restart|reload}" |
| exit 1 |
| esac |