0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第四篇 嵌入式Linux系统移植篇-第六十七章 Uboot编译及移植

北京迅为电子 2024-08-07 15:08 次阅读

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业以太网、MIPI-DSIUSB HOST、WIFI/BT、4G模块CANRS485接口一应俱全。H264、VP8视频硬编码,H.264、H.265、VP8、VP9视频硬解码,并提供相关历程,支持8路PDM接口、5路SAI接口、2路Speaker。系统支持Android9.0(支持获取root限)Linux4.14.78+Qt5.10.1、Yocto、Ubuntu20、Debian9系统。适用于智能充电桩物联网工业控制,医疗,智能交通等,可用于任何通用工业和物联网应用。

第四篇 嵌入式Linux系统移植篇

第六十七章 Uboot编译及移植

在之前学习开发板烧写的章节中,我们用到uboot和内核的镜像是怎么做出来的呢,我们在学习移植uboot之前先使用迅为电子移植好的uboot镜像来学习一下uboot的相关知识,本章节我们来学习下基础的知识“什么是uboot”和“uboot中的常用命令”,并且我们下载NXP官方的源码。

67.1 U-Boot介绍

67.1.1 什么是u-boot

uboot是一段裸机代码,它的实现非常复杂,主要是初始化一些硬件,部署整个计算机系统,然后将Linux内核从flash(NAND,NOR FLASH,SD,MMC 等)拷贝到 DDR 中,根据环境变量去启动内核,并向内核传递参数。它的目标就是启动内核,内核启动后它的生命也随之结束。

u-boot是SourceForge上的开源项目,由一个人发起,然后由整个世界所有感兴趣的人共同维护发展而来的一个bootloader,bootloader是用来引导和加载内核,向内核传递参数的,是内核引导程序的统称,bootloader除了u-boot还有bios,LilO,redboot,vivi等。

uboot 的全称是 Universal Boot Loader,uboot 是一个遵循 GPL 协议的开源软件,uboot 是一个裸机代码,可以看作是一个裸机综合例程。现在的 uboot 已经支持液晶屏、网络、USB 等高级功能。uboot 官网为 http://www.denx.de/wiki/U-Boot/,

可以在 uboot 官网下载 uboot 源码,点击图中左侧 Topics 中的“Source Code”,

进入其 FTP 服务器即可看到 uboot 源码

wKgaomazHPGAHrSUAAGk04JdyRA648.png

我们可以在uboot官网下载最原始的uboot源码,也就是没有经过修改的,原汁原味的uboot的,但是在实际工作中,我们并不会直接在uboot官网下载uboot源码来移植uboot。为什么呢?因为我们要在对应的平台上来运行uboot,那么这个uboot是不是就要对这个平台支持的非常全面呢,因为uboot本身就是裸机代码,所以想要对某一个平台支持的非常全面,就要对这个平台非常熟悉,比如i.MX 8M Mini,那就要对i.MX 8M Mini这个芯片非常熟悉,那谁对这个芯片非常熟悉呢,当然是半导体厂家呀,所以,uboot官网里面的原汁原味的uboot是给半导体厂家准备的,比如RK,NXP等等。NXP官方的 uboot 基本支持了 NXP 当前所有可以跑 Linux 的芯片,而且支持各种启动方式,比如 EMMC、NAND、NOR FLASH 等等,这些都是 uboot 官方所不支持的。我们如果要移植对芯片支持最全面,最好的uboot的,我们一般是在半导体厂家维护uboot版本的基础上来二次开发自己的uboot,而不是直接在uboot官网下载源码来移植。

在迅为提供的资料里面有两个Linux的BSP源码包,一个是半导体厂商提供的源码包,里面的uboot是未经修改的,一个是迅为提供的BSP源码包,里面的uboot是经过迅为修改后的uboot,可以直接编译在开发板上来运行。当然了,你也可以在购买了第三方开发板以后使用半导体厂商提供的 uboot,只不过有些外设驱动可能不支持,需要自己移植,这个就是我们常说的 uboot 移植。

67.1.2 常用命令

我们先烧迅为做好的uboot(flash.bin)到开发板上,我们先了解与uboot相关的命令。

uboot启动如下图所示:

wKgaomazHPmAYSSCAAB8mUfpGbQ001.png

上电以后,出现 Hit any key to stop autoboot: 0就按下任意键,进入uboot命令行,输入?查看帮助信息,会弹出很多命令和介绍,

上面的那些命令并不是 uboot 所支持的所有命令,前面说过 uboot 是可配置的,需要什么命令就使能什么命令。这些命令后面都跟有命令说明,用于描述此命令的作用,但是命令具体怎么用呢?我们输入“help(或?) 命令名”既可以查看命令的详细用法,以“bootz”这个命令为例,我们输入如下命令即可查看“bootz”这个命令的用法:

=> ? bootz

bootz - boot Linux zImage image from memory

Usage:

bootz [addr [initrd[:size]] [fdt]]

- boot Linux zImage stored in memory

The argument 'initrd' is optional and specifies the address

of the initrd in memory. The optional argument ':size' allows

specifying the size of RAW initrd.

When booting a Linux kernel which requires a flat device-tree

a third argument is required which is the address of the

device-tree blob. To boot that kernel without an initrd image,

use a '-' for the second argument. If you do not pass a third

a bd_info struct will be passed instead

常用的和信息查询有关的命令有 3 个:

bdinfo

printenv

version

先来看一下 bdinfo 命令,此命令用于查看板子信息,直接输入“bdinfo”即可,

从上面中可以得出 DRAM 的起始地址和大小、启动参数保存起始地址、波特率、sp(堆栈指针)起始地址等信息。

命令“printenv”用于输出环境变量信息,uboot 也支持 TAB 键自动补全功能,输入“print”然后按下 TAB 键就会自动补全命令,直接输入“print”也可以。输入“print”,然后按下回车键,环境变量如下面所示:

wKgZomazHSeAI7m6AAFqiOn4TMM019.png

u-boot=> pri

baudrate=115200

boot_fdt=try

bootcmd=mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else booti ${loadaddr} - ${fdt_addr}; fi

bootcmd_mfg=run mfgtool_args;if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else booti ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot 0; fi;

bootdelay=2

bootscript=echo Running bootscript from mmc ...; source

console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200

emmc_dev=1

ethprime=FEC

fastboot_dev=mmc1

fdt_addr=0x43000000

fdt_file=itop8mm-evk-7.0.dtb

fdt_high=0xffffffffffffffff

fdtcontroladdr=be8f5860

image=Image

initrd_addr=0x43800000

initrd_high=0xffffffffffffffff

jh_clk=

jh_mmcboot=setenv fdt_file fsl-imx8mm-evk-root.dtb;setenv jh_clk clk_ignore_unused; if run loadimage; then run mmcboot; else run jh_netboot; fi;

jh_netboot=setenv fdt_file fsl-imx8mm-evk-root.dtb; setenv jh_clk clk_ignore_unused; run netboot;

kboot=booti

loadaddr=0x40480000

loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};

loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}

loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}

mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused

mmcargs=setenv bootargs ${jh_clk} console=${console} root=${mmcroot}

mmcautodetect=yes

mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else echo wait for boot; fi;

mmcdev=1

mmcpart=1

mmcroot=/dev/mmcblk2p2 rootwait rw

netargs=setenv bootargs ${jh_clk} console=${console} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp

netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${loadaddr} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else booti; fi;

script=boot.scr

sd_dev=0

soc_type=imx8mm

Environment size: 2333/4092 bytes

有很多的环境变量,比如 baudrate、board_name、board_rec、boot_fdt、bootcmd等等。uboot 中的环境变量都是字符串,既然叫做环境变量,那么它的作用就和“变量”一样。

比如 bootdelay 这个环境变量就表示 uboot 启动延时时间,默认bootdelay=3,也就默认延时 3秒。前面说的 3 秒倒计时就是由 bootdelay 定义的,如果将 bootdelay 改为 5 的话就会倒计时 5s了。uboot 中的环境变量是可以修改的,有专门的命令来修改环境变量的值。

setenv:修改环境变量:setenv 环境变量名 环境变量值

删除环境变量:setenv 环境变量名

例如设置自启动倒计时环境变量bootdelay,设置为5秒,默认是2秒,

输入命令setenv bootdelay 10,然后输入printenv查看环境变量,发现环境变量已经改变。

删除环境变量也是使用命令 setenv,要删除一个环境变量只要给这个环境变量赋空值即可,比如我们删除掉上面新建的bootdelay 环境变量,使用命令 setenv bootdelay删除环境变量,

实验完成后,重新启动开发板恢复环境变量使设置的环境失效,因为环境变量没有保存到flash。

reset:重新启动

在uboot命令行输入reset即可重启开发板,

实验完成后,重新启动开发板恢复环境变量使设置的环境失效,因为环境变量没有保存到flash。

reset:重新启动

在uboot命令行输入reset即可重启开发板,

1.mmc: 在uboot命令行,输入mmc可以查看跟mmc相关的命令

由上图我们可以发现,mmc后面的参数不同,mmc的功能就不一样,例如:

mmc info:打印mmc的信息

mmc list :查看mmc设备

mmc read addr blk# cnt:从eMMC读cnt个块数据到内存addr处;

mmc write addr blk# cnt:把内存addr处的cnt个块数据写到eMMC。

mmc erase blk# cnt:擦除blk#开始的cnt个数据块

其中,addr为内存地址,blk#是mmc的块号,cnt是设备块的个数,块的单位是512字节。

(1)mmc info命令

mmc info命令可以查看设备信息,

通过上图我们可以看出,当前的设备是emmc设备,也就是图中MMC version所表示的信息为emmc的版本为5.1,Capacity所表示的信息为容量大小为14.6 Gib,Bus Width表示带宽为8-bit,Bus Speed表示速度为52000000Hz。

(2)mmc list命令

mmc list查看mmc设备,直接输入mmc list即可,

(3)mmc rescan命令

mmc rescan可以扫描开发板上的emmc设备,直接输入mmc rescan命令即可

(4)mmc dev命令

mmc dev命令可以切换mmc设备,命令格式:mmc dev mmc dev [dev] [part],其中dev是我们要切换到的mmc设备号,part可以不写,不写的话默认分区为0。

我们找一张FAT32的TF卡,查到开发板上的TF卡座子上,一般我们把TF卡也认为是mmc设备。所以也可以用mmc命令来操作。连接好TF卡以后,使用以下命令切换到TF卡

mmc dev 0

其中0为sd卡,1为emmc。

然后我们使用mmc info命令查看是否切换成功,

从上图我们可以看到,sd卡的版本信息为3.0,容量为14.6 GiB,位宽为4-bit。

(5)mmc part命令

mmc part可以用来查看mmc设备的分区,比如我们要查看emmc的分区,我们先切换到emmc设备(如果当前已经是emmc设备则不用切换),命令如下:

mmc dev 1

切换成功如下图所示:

wKgZomazHUKASusVAAAMFRSyuf0695.png

使用命令mmc part查看emmc的分区,

从上图我们可以看出,emmc一共有2个分区,类型为DOS,其中第一个分区用来存放uboot镜像和内核镜像,第二个分区用来存放文件系统

(6)mmc read命令

使用mmc read命令可以读取mmc设备的数据信息,格式为mmc read addr blk# cnt,其中addr是读取到内存中的地址,blk为起始的块地址,一般为十六进制,一块是512字节,cnt是要读取的块的数量。

例如:mmc read 0xa0000000 10 10 ,表示mmc设备的第10块开始,读取10块到内存的0xa0000000地址当中去。结果如下:

5 go命令

go命令可以指定跳到地址处运行,命令格式为 go addr ,其中addr是应用在内存中的首地址。

6 run命令

可以执行环境变量中的命令,这个命令一般用于用户运行自定义的环境变量。

7 ls命令,默认uboot没有这个命令,可以配置上使用。

ls命令可以列出文件的目录,命令格式ls [ [directory]]:

例如,查看emmc分区5的信息。分区5为文件系统分区

ls mmc 1:5

其中,1为emmc,5为emmc里面的分区5

查看emmc分区5里面的etc信息,也就是文件系统里面的etc信息,命令如下

ls mmc 1:5 etc

67.2设置交叉编译器

输入以下命令设置交叉编译器,只有设置了交叉编译器,才可以编译源码,否则会报错。

. /opt/fsl-imx-xwayland/4.14-sumo/environment-setup-aarch64-poky-linux

export ARCH=arm64

export CROSS_COMPILE=aarch64-poky-linux-

67.3 获取u-boot-imx 源码并编译

输入以下命令下载u-boot-imx 源码。

git clone https://source.codeaurora.org/external/imx/uboot-imx

进入uboot-imx目录,

cd uboot-imx

查看git分支,

git branch -a

切换分支,输入以下命令:

git checkout imx_v2018.03_4.14.78_1.0.0_ga

同步到当前仓库,输入以下命令:

git pull origin

输入以下命令,开始编译。

make distclean

make imx8mm_ddr4_evk_defconfig

输入以下命令,开始编译。

. /opt/fsl-imx-xwayland/4.14-sumo/environment-setup-aarch64-poky-linux

make -j 8

编译成功后会产生所需的文件:

u-boot-nodtb.bin

spl/u-boot-spl.bin

arch/arm/dts/fsl-imx8mm-ddr4-evk.dtb

67.4 获取 imx-mkimage源码并编译

下载 imx-mkimage源码,输入以下命令:

git clone https://source.codeaurora.org/external/imx/imx-mkimage/ && cd imx-mkimage

查看远程分支,输入以下命令:

git branch -a

切换到与imx_4.14.78_1.0.0_ga版本对应的分支上,输入以下命令:

git checkout imx_4.14.78_1.0.0_ga

同步到当前仓库,输入以下命令:

git pull origin

67.5获取imx-atf源码并编译

退回上一级目录,下载 imx-atf,并同样切换分支

cd ..

git clone https://source.codeaurora.org/external/imx/imx-atf/ && cd imx-atf

切换到与imx_4.14.78_1.0.0_ga版本对应的分支上,输入以下命令:

git checkout imx_4.14.78_1.0.0_ga

同步到当前仓库,输入以下命令:

git pull origin

编译 imx-atf,输入以下命令:

make clean PLAT=imx8mm

LDFLAGS="" make PLAT=imx8mm

编译完成会生成build/imx8mm/release/bl31.bin文件,

67.6 获得firmware-imx源码

返回上一级目录,输入以下命令获得firmware-imx源码

cd .. && mkdir firmware-imx-8.10

cd firmware-imx-8.10

wget http://www.freescale.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.1.bin

解压输入以下命令:

./firmware-imx-8.1.bin --auto-accept

67.7生成flash.bin

使用 imx-mkimage 链接合成所有文件生成最后二进制文件

输入以下命令拷贝uboot-imx中的文件到imx-mkimage目录。

cp uboot-imx/tools/mkimage ./imx-mkimage/iMX8M/mkimage_uboot

cp uboot-imx/arch/arm/dts/fsl-imx8mm-ddr4-evk.dtb ./imx-mkimage/iMX8M/fsl-imx8mm-ddr4-evk.dtb

cp uboot-imx/spl/u-boot-spl.bin ./imx-mkimage/iMX8M/

cp uboot-imx/u-boot-nodtb.bin ./imx-mkimage/iMX8M/

cpfirmware-imx-8.10/firmware-imx-8.1/firmware/ddr/synopsys/ddr4_dmem_1d.bin ./imx-mkimage/iMX8M/

cpfirmware-imx-8.10/firmware-imx-8.1/firmware/ddr/synopsys/ddr4_dmem_2d.bin ./imx-mkimage/iMX8M/

cp firmware-imx-8.10/firmware-imx-8.1/firmware/ddr/synopsys/ddr4_imem_1d.bin ./imx-mkimage/iMX8M/

cp firmware-imx-8.10/firmware-imx-8.1/firmware/ddr/synopsys/ddr4_imem_2d.bin ./imx-mkimage/iMX8M/

cp imx-atf/build/imx8mm/release/bl31.bin ./imx-mkimage/iMX8M/

cd imx-mkimage

make SOC=iMX8MM clean

make SOC=iMX8MM flash_ddr4_evk

编译完会生成flash.bin镜像,

然后我们可以使用TF卡启动uboot,但是不能使用UUU工具烧写,接下来进一步优化源码,请查看第二章。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5083

    文章

    19129

    浏览量

    305398
  • Linux
    +关注

    关注

    87

    文章

    11306

    浏览量

    209569
  • Uboot
    +关注

    关注

    4

    文章

    125

    浏览量

    28240
  • RK3568
    +关注

    关注

    4

    文章

    514

    浏览量

    5058
收藏 人收藏

    评论

    相关推荐

    i.MX6ULL嵌入式Linux开发1-uboot移植初探

    本系列教程以i.MX6ULL处理器的ARM开发实验基础,学习记录嵌入式Linux开发的各种知
    的头像 发表于 03-07 08:57 3889次阅读
    <b class='flag-5'>i.MX</b>6ULL<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b><b class='flag-5'>开发</b>1-<b class='flag-5'>uboot</b><b class='flag-5'>移植</b>初探

    韦东山嵌入式Linux应用开发完全手册.pdf电子版

    驱动程序移植第5 嵌入式Linux系统应用开发
    发表于 09-18 17:08

    ARM嵌入式Linux系统开发详解

    GUI程序开发第12软件项目管理第3Linux系统第13
    发表于 09-14 08:57

    嵌入式Linux开发流程中的各个步骤

    基础第三 ARM体系架构第四章 嵌入式编程开发入门第五 软硬件
    发表于 11-04 07:37

    RK3399开发嵌入式linux开发流程

    RK3399开发嵌入式linux开发指南
    发表于 11-04 08:08

    iMX6ULL开发板使用手册资料下载

    开发板使用手册》第一部分 开发板入门第二部分 开发环境搭建第三部分 Linux系统编译第四
    发表于 12-02 14:13

    【倾心力作!】i.MX8MM嵌入式linux开发指南+全覆盖开发资料

    第六十三章 输入子系统实验第六十四章 Linux 12C驱动第六十五章 Linux 12C驱动实
    发表于 02-11 10:27

    资料上新】iTOP-3568开发指南手册!

    很多零基础的同学在刚开始学习嵌入式的时候,都会不知道应该怎么做,精心编写了适配iTOP-rk3568开发板的嵌入式教程-《【
    发表于 04-26 15:03

    Linux嵌入式Linux系统移植(上篇:交叉编译器、连接方式)

    移植要点搭建交叉开发环境bootloader的选择与移植kernel的设置、编译移植和调试根文件系统
    发表于 11-01 16:57 14次下载
    【<b class='flag-5'>Linux</b>】<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b><b class='flag-5'>系统</b>的<b class='flag-5'>移植</b>(上篇:交叉<b class='flag-5'>编译</b>器、连接方式)

    RK3399开发嵌入式linux开发指南

    RK3399开发嵌入式linux开发指南
    发表于 11-01 16:58 77次下载
    <b class='flag-5'>迅</b><b class='flag-5'>为</b>RK3399<b class='flag-5'>开发</b>板<b class='flag-5'>嵌入式</b><b class='flag-5'>linux</b><b class='flag-5'>开发指南</b>

    [深度理解嵌入式linux系统移植]深度理解嵌入式linux系统移植

    第一-嵌入式系统架构与移植环境搭建第二-uboot工程与
    发表于 11-02 13:21 17次下载
    [深度理解<b class='flag-5'>嵌入式</b><b class='flag-5'>linux</b><b class='flag-5'>系统</b><b class='flag-5'>移植</b>]深度理解<b class='flag-5'>嵌入式</b><b class='flag-5'>linux</b><b class='flag-5'>系统</b><b class='flag-5'>移植</b>

    【正点原子Linux连载】第十二官方SDK移植试验-摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    【正点原子Linux连载】第十二官方SDK移植试验-摘自【正点原子】I.MX6U嵌入式Linux
    发表于 11-23 17:51 11次下载
    【正点原子<b class='flag-5'>Linux</b>连载】第十二<b class='flag-5'>章</b>官方SDK<b class='flag-5'>移植</b>试验-摘自【正点原子】<b class='flag-5'>I.MX</b>6U<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>驱动<b class='flag-5'>开发指南</b>V1.0

    【正点原子Linux连载】第六十七章 Linux USB驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    :http://www.openedv.com/thread-300792-1-1.html3)对正点原子Linux感兴趣的同学可以加群讨论:9354467414)关注正点原子公众号,获取最新资料更新第六十七章 Linux US
    发表于 12-22 18:56 10次下载
    【正点原子<b class='flag-5'>Linux</b>连载】<b class='flag-5'>第六十七章</b> <b class='flag-5'>Linux</b> USB驱动实验 -摘自【正点原子】<b class='flag-5'>I.MX</b>6U<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>驱动<b class='flag-5'>开发指南</b>V1.0

    北京】《stm32mp157开发嵌入式linux开发指南》第五 Ubuntu使用apt-get下载

    北京】《stm32mp157开发嵌入式linux开发
    的头像 发表于 09-03 16:26 794次阅读
    【<b class='flag-5'>北京</b><b class='flag-5'>迅</b><b class='flag-5'>为</b>】《stm32mp157<b class='flag-5'>开发</b>板<b class='flag-5'>嵌入式</b><b class='flag-5'>linux</b><b class='flag-5'>开发指南</b>》第五<b class='flag-5'>章</b> Ubuntu使用apt-get下载

    北京i.mx8mm嵌入式linux开发指南第四篇 嵌入式Linux系统移植第六十九章uboot移植

    北京i.mx8mm嵌入式linux开发指南
    的头像 发表于 10-22 14:46 633次阅读
    【<b class='flag-5'>北京</b><b class='flag-5'>迅</b><b class='flag-5'>为</b>】<b class='flag-5'>i.mx8mm</b><b class='flag-5'>嵌入式</b><b class='flag-5'>linux</b><b class='flag-5'>开发指南</b><b class='flag-5'>第四篇</b> <b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b><b class='flag-5'>系统</b><b class='flag-5'>移植</b><b class='flag-5'>篇</b><b class='flag-5'>第六十</b>九章<b class='flag-5'>uboot</b><b class='flag-5'>移植</b>