uboot中利用TFTP和NFS加载内核镜像和根文件系统

本文介绍如何在U-Boot环境下通过NFS和TFTP加载内核镜像和根文件系统,包括配置步骤、常见问题解决方法以及简化操作技巧。

uboot中利用TFTP和NFS加载内核镜像和根文件系统

主机说明:
主机guest 为虚拟机redhat9: IP: 59.64.155.122  网关 59.64.155.1
redhat9上已经配置好NFS服务(参考http://blog.chinaunix.net/u2/80953/showart.php?id=1274973)
也已经配置好TFTP服务(参考http://blog.chinaunix.net/u2/80953/showart.php?id=1274976)
NFS服务, TFTP服务都已经启动
终端采用主机host XP的超级终端

实验板说明:
MPC8349itx开发板: IP: 59.64.155.244  网关 59.64.155.1
开发板eth0为vsc8201芯片,uboot支持驱动,另一芯片为交换交换芯片vsc7385,单独模块驱动。
U-Boot-1.1.3 ;    Linux kernel-2.6.13
内核支持NFS分区(即编译时在File system中选中[*] Root file system on NFS), 以及支持内核IP_PNP(即编译时在Networking中选中[*] IP: kernel level autoconfiguration)
    File systems  --->
        Network File Systems  --->
            <*> NFS file system support                        ## 必选
                [*]   Provide NFSv3 client support             ## 可选
            [*] Root file system on NFS                        ## 必选
    Networking  --->
        [*] Networking support
            Networking options  --->
                [*]   IP: kernel level autoconfiguration       ## 必选

***************************************************************************

A: NFS启动挂载根文件系统

主机上操作:
$ cd /usr/local/mpc8349/
$ ./ltib --preconfig config/platform/mpc8349itx/defconfig-min-fs -f
    ## 依次进入如下选项选择(X) NFS only, 根据情况决定是否选择[ ] read-only root filesystem
    --- Target Image Generation
        Options  --->
        --- Choose your root filesystem image type
             Target image: (ext2.gz ramdisk)  --->         ## 改ramdisk文件系统为NFS
            (X) NFS only
            [ ] read-only root filesystem
    ## 其他情况参考LTIB使用说明(http://blog.chinaunix.net/u2/80953/showart.php?id=1275002)
    ## 编译结束后生成的根文件系统是位于当前安装目录下的rootfs (/usr/local/mpc8349/small/rootfs)

$ ln -s /usr/local/mpc8349/small/rootfs  /home/liuby/rootfsln    ## 建立NFS服务目录软连接
$ su - root        ## 切换到root用户,需要密码
# echo "/usr/local/mpc8349/small/rootfs  59.64.155.244(rw,sync,no_root_squash)" > /etc/exports     ## NFS 服务配置
# service portmap restart
# service nfs restart
# exportfs -arv        ## 修改的NFS配置生效(exportfs参数顺序不一样,显示有所不同,此顺序显示结果明了)
# exit


实验板上操作:
uboot启动后按键进入uboot命令行环境:
=> cp.b fef50000 40000 20000; go 40004        ## 驱动vsc7385芯片
=> set serverip 59.64.155.122          ## 主机地址
=> set ipaddr 59.64.155.244            ## 实验板地址
=> set netmask 255.255.255.0
=> set netdev eth0                     ## eth0
=> ping 59.64.155.122                  ## 测试连通
=> set hostname PowerQUICC
=> set kernaddr fe810000            ## flash中内核起始地址
=> set rootpath /usr/local/mpc8349/small/rootfs        ## NFS服务根目录
=> setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=ttyS0,115200
=> bootm $kernaddr
            ## 如果一切正常,内核启动后会启动NFS文件系统作根文件系统。
            ## 测试: 在开发板上创建一个文件,在主机上会看到这个文件生成
同样可以简化操作(测试nfs服务软连接目录):
=> cp.b fef50000 40000 20000; go 40004        ## 驱动vsc7385芯片
=> setenv ipaddr 59.64.155.244
=> setenv bootargs root=/dev/nfs rw nfsroot=59.64.155.122:/home/liuby/rootfsln ip=59.64.155.244:59.64.155.122:255.255.255.0 console=ttyS0,115200
=> bootm fe810000            ## 内核镜像uImage在FLASH中的存储地址

************************

实验中遇到一个问题,就是bootm之后内核启动,NFS启动挂载文件系统快完成时出现下面这个错误提示
RPC: sendmsg returned error 101
nfs: RPC call returned error 101
后来才发现是文件系统中的启动脚本在启动过程中修改了eth0的ip地址,导致连接不上NFS server
后来再测试又发现试图挂载非NFS文件系统目录时也会出现此问题,并且在主机上执行# showmount 命令结果会显示有ip地址(实验板ip地址)挂载。即: 在ltib编译文件系统时选择ext2.gz ramdisk (非NFS only), 最后使用rootfs目录,出现同样的问题。

还有遇到过一个问题,根本无法挂载文件系统,在启动时出现下述提示
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
 <0>Rebooting in 180 seconds..
后来发现是 /etc/exports 只有如下一句
 /home/liuby/rootfs  59.64.155.244(rw,sync,no_root_squash)
而没有像下面这样指定根目录的访问权限:
 /usr/local/mpc8349/small/rootfs  59.64.155.244(rw,sync,no_root_squash)
结论: 必须指定NFS文件系统所在目录或其对应的软连接做NFS服务根目录(见下分析)

在NFS文件系统中编译busybox时可以不选择编译mount命令(不建议如此)

nfs总结:
如上 /home/liuby/rootfsln是指向/usr/local/mpc8349/small/rootfs的软连接
# echo "/home/liuby/rootfsln 59.64.155.244(rw,sync,no_root_squash)" > /etc/exports
# exportfs -arv             ## 会弹出下面的提示
exporting 59.64.155.244:/usr/local/mpc8349/small/rootfs
可见 /etc/exports 中语句 /home/liuby/rootfsln 59.64.155.244(rw,sync,no_root_squash) 和 /usr/local/mpc8349/small/rootfs  59.64.155.244(rw,sync,no_root_squash) 是等效的.
故: 如果想用不同的文件系统,可以改变这个软连接指向新的文件系统,这比复制文件系统或者修改u-boot环境变量方便多了,并且还不用重新配置/etc/exports。
# echo "/home/liuby/rootfsln 59.64.155.244(rw, sync, no_root_squash)" > /etc/exports
$ rm -f /home/liuby/rootfsln
$ ln -s nfs_rootfs_dir_path  /home/liuby/rootfsln            ## 只需要建立和修改这个软连接即可
# exportfs -arv            ## 配置生效(必须)
在uboot环境变量中只需设置一次rootpath=/home/liuby/rootfsln, 每次只需在主机上修改此软连接的指向,即可
注意权限
***************************************************************************

B: TFTP下载内核和文件系统镜像到ram中启动

主机上操作:
在主机上TFTP根目录为/home/liuby/tftpboot/
$ mkdir /home/liuby/tftpboot/image_dir
$ cd /usr/local/mpc8349/small/
$ ./ltib --preconfig config/platform/mpc8349itx/defconfig-min-fs-modified -f --batch          ## 编译内核和文件系统镜像
$ cp -f rootfs/boot/uImage  rootfs.ext2.gz.uboot  ~/tftpboot/image_dir/        ## 复制内核镜像和文件系统镜像到~/tftpboot/image_dir
$ cd ~/tftpboot/
$ ln -s image_dir/ bootln


实验板上操作:
=> set serverip 59.64.155.122          ## 主机地址
=> set ipaddr 59.64.155.244            ## 实验板地址
=> set netmask 255.255.255.0
=> set tftp_path bootln
=> ping $serverip                      ## 测试连通
=> cp.b fef50000 40000 20000; go 40004        ## 驱动vsc7385芯片
=> setenv loadkernaddr 1000000
=> setenv loadramdaddr 1200000
=> tftpboot $loadkernaddr image_dir/uImage    ## 下载内核镜像到ram
=> tftp $loadramdaddr $tftp_path/rootfs.ext2.gz.uboot    ## 下载文件系统镜像到ram
=> bootm $loadkernaddr $loadramdaddr    ## 启动ram中内核和文件系统镜像

下载不畅时,用CTRL+C来终止回到提示符


tftp总结:
在TFTP服务根目录下建立目录存储镜像文件,然后创建软连接指向需要下载的镜像目录,这样可以通过修改连接文件即可,而不用每次修改uboot环境变量了

***************************************************************************

C: TFTP下载内核镜像到ram,NFS挂载根文件系统(target image: NFS only)

主机上利用上面操作的结果,不进行配置。
实验板上操作:
=> set serverip 59.64.155.122          ## 主机地址
=> set ipaddr 59.64.155.244            ## 实验板地址
=> set netmask 255.255.255.0
=> set bootargs root=/dev/nfs rw nfsroot=$serverip:/home/liuby/rootfsln ip=$ipaddr:$serverip:$netmask console=ttyS0,115200
=> tftp 1000000 bootln/uImage          ## 下载内核镜像到ram 地址1000000
=> bootm 1000000
                ## 测试发现内核启动,NFS挂载成功

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

简便方法:
将下面附录的文件存储为.txt文件,例如取名mpc8349itx_uboot_env.txt
用linux命令unix2dos进行转换,然后打开windows XP 超级终端,启动实验板进入uboot命令行环境:
点击超级终端界面 "文件"->"属性",弹出属性对话框,点击"设置"->"ASCII码设置",设置行延迟20ms,字符延迟1ms;然后点击"发送"->"发送文本文件",选择"mpc8349itx_uboot_env.txt"发送。
此操作相当于在uboot命令行输入uboot环境设置参数
执行完操作后保存了这些设置,以后每次在uboot启动时不用再敲入一行行的设置参数.

在uboot命令行下执行
=> run flashnfsboot
相当于 A 操作

在uboot命令行执行
=> run tftpramboot
相当于执行 B 操作

在uboot命令行执行
=> run tftpnfsboot
相当于执行 C 操作

转栽地址:http://blog.chinaunix.net/u3/98913/showart_1978279.html

<think>我们正在讨论嵌入式系统中U-Boot、内核根文件系统的烧写工具及烧写位置问题。根据之前的对话,用户已经了解U-Boot通常不会覆盖分区表,因为它在存储设备上的起始位置通常是1KB偏移处(0x400)。现在用户进一步询问关于烧写工具烧写位置确定的问题。 参考引用: [^1]:提到了在嵌入式烧写中,U-Boot是推荐使用的引导程序,它支持多种目标板体系结构。 [^2]:提到在IMX6ULL平台上,使用mfgtool烧写工具将U-Boot、内核、设备树根文件系统烧写到EMMC中。 [^3]:提到在U-Boot中使用bootm命令启动内核,需要指定内核镜像根文件系统设备树的地址。 因此,我们需要回答两个主要问题: 1. 烧写工具:在嵌入式移植中,常用的烧写工具有哪些? 2. 烧写位置:烧写位置是否需要确定?如果需要,如何确定? 针对第一个问题,烧写工具: - 在开发阶段,通常使用JTAG、USB或者串口等工具通过特定的烧写软件将引导程序(如U-Boot)烧写到存储设备的指定位置。 - 一旦U-Boot启动成功,就可以通过U-Boot提供的命令(如tftpnfs、usb、mmc等)来烧写内核根文件系统。 - 常用的烧写工具包括: - 生产烧写工具(如mfgtool,用于i.MX系列)[^2] - U-Boot自带的命令(如dd、tftp、nand write等) - 其他工具(如OpenOCD、J-Flash等用于JTAG烧写) 针对第二个问题,烧写位置: - 烧写位置必须确定,因为系统启动过程中,硬件会从固定的地址加载引导程序,然后引导程序会按照预定义的地址去加载内核根文件系统。 - 存储设备的分区布局通常在U-Boot中定义(通过环境变量或设备树),或者在分区表中定义(如MMC设备的分区表)。 具体到每个组成部分: 1. U-Boot:通常烧写在存储设备的起始位置(但避开分区表,如SD卡从1KB开始)。具体的地址由硬件决定,例如,i.MX6ULL的启动ROM会从存储设备的固定位置(如SD卡的第1KB处)加载U-Boot。 2. 内核镜像(zImage或uImage设备树:烧写的位置必须在U-Boot的环境变量中指定,比如`loadaddr`(加载地址)`fdt_addr`(设备树地址)。通常内核烧写在内存中运行,但镜像本身存储在存储设备的特定分区(如MMC的第二个分区)中。 3. 根文件系统:通常烧写在单独的分区(如MMC的第三个分区)。它的位置由内核启动参数(bootargs)中的`root`参数指定。 总结步骤: 1. 确定硬件启动要求:比如SoC的启动ROM从哪个地址开始加载引导程序。 2. 规划存储设备的分区:通常包括: - 分区1:bootloader分区(存放U-Boot) - 分区2:内核分区(存放内核镜像设备树) - 分区3:根文件系统分区 3. 烧写工具根据分区规划将各个组件烧写到对应位置。 因此,回答如下: </think>### 嵌入式移植烧写工具与位置详解 #### 一、烧写工具概述 1. **U-Boot烧写工具** - **低级烧写**:使用硬件编程器(如J-Link)直接烧录NOR/NAND Flash ``` JFlash.exe -open u-boot.bin -auto -exit ``` - **量产工具**: - NXP平台:`mfgtool`[^2] - Rockchip平台:`RKDevTool` - **开发阶段**:U-Boot自身支持`tftp`或`USB-OTG`烧写升级 ```bash tftp 0x82000000 u-boot.imx mmc write 0x82000000 0x2 0x800 ``` 2. **内核根文件系统烧写** - **U-Boot命令**: ```bash # 烧写内核 ext4load mmc 1:2 0x80800000 zImage # 烧写根文件系统 ext4write mmc 1:3 0x81000000 rootfs.tar 0x1000000 ``` - **量产工具集成**:如`mfgtool`一键烧写内核+DTB+根文件系统[^2] - **网络传输**:通过`NFS`挂载根文件系统调试(无需物理烧写)[^3] #### 二、烧写位置关键要求 | 组件 | 典型烧写位置 | 位置决定因素 | |-------------|---------------------------------|-----------------------------| | **U-Boot** | SD卡: 1KB偏移(0x400)[^2] | SoC BootROM固定加载地址 | | | NOR Flash: 0x00000000 | | | **内核** | MMC分区2(/dev/mmcblk0p2) | U-Boot环境变量`bootcmd`指定 | | | 内存加载地址:0x41000000[^3] | | | **根文件系统**| MMC分区3(/dev/mmcblk0p3) | 内核参数`root=/dev/mmcblk0p3` | | **设备树** | 紧邻内核(如0x43000000)[^3] | U-Boot传参约定 | > **位置验证方法**: > 1. U-Boot位置:通过芯片手册确认BootROM加载地址 > 2. 内核位置:`printenv`查看`bootcmd`中的加载地址 > 3. 分区位置:`fdisk -l /dev/mmcblk0`确认分区布局 > 4. 根文件系统内核启动参数`cat /proc/cmdline` #### 三、烧写位置冲突防护 1. **分区表保护机制** - U-Boot烧写命令自动跳过保护区(SD卡前1KB) ```bash dd if=u-boot.bin of=/dev/sdb seek=1 bs=1k # 关键seek参数[^2] ``` 2. **边界校验脚本示例** ```bash #!/bin/bash BOOT_SIZE=$(stat -c%s u-boot.bin) if [ $BOOT_SIZE -gt 1048576 ]; then # 超过1MB保护区时报错 echo "错误:U-Boot镜像超过保护区大小!" exit 1 fi ``` #### 四、典型烧写流程 ```mermaid graph TD A[准备镜像] --> B[连接设备] B --> C{存储介质类型} C -->|SD卡| D[dd烧写U-Boot] C -->|eMMC| E[mfgtool量产] D/E --> F[启动U-Boot] F --> G[tftp加载内核/DTB] F --> H[ext4write烧写根文件系统] H --> I[设置bootargs] I --> J[启动系统] ``` > **烧写位置必须精确确定**: > - SoC硬件固定加载U-Boot地址不可更改 > - 内核加载地址需匹配内存映射表 > - 根文件系统位置需与内核参数严格一致 > 否则会导致启动失败(常见错误:内核解压地址覆盖U-Boot) --- ### 相关问题 1. 如何修改U-Boot环境变量中的默认内核加载地址? 2. 当使用TFTP烧写内核时出现校验错误应如何解决? 3. 如何为eMMC设备创建带保护区的分区表? 4. 为什么NFS挂载根文件系统时需要特定内核配置选项? 5. 在多核处理器架构中设备树地址传递有何特殊要求?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值