Uboot如何引导系统
2015-06-09 11:11
267 查看
通过串口连接BeagleBone Black,参见http://elinux.org/Beagleboard:Terminal_Shells
启动到U-Boot的时候,会看到
Hit any key to stop autoboot:0
复制代码
按下任意键则放弃了自动引导,从而进入了U-Boot的命令行。
在这里你可以手动进行接下来系统的引导。但是我不会。
虽然不会,但是用于板子上的系统有自动引导,
我们可以分析自动引导,来了解U-Boot是如何引导系统的。
在U-Boot的官网手册中看到了2个关键的环境变量和1个命令。
bootcmd: This variable defines a command string that is automatically executed
when the initial countdown is not interrupted.
This command is only executed when the variable bootdelay is also defined!
bootargs: The contents of this variable are passed to the Linux kernel as boot
arguments (aka "command line").
run - run commands in an environment variable
bootcmd中的命令就是出现“Hit any key to stop autoboot”提示后,不按任意键,会自动运行的命令。
bootargs是传递给Linux内核的参数。
run是运行环境变量中的命令,bootcmd中包含run命令。
所以分析引导过程要从bootcmd开始。
在U-Boot的命令行中输入printenv可显示所有的环境变量,我已经把相关的粘贴到了下面。
为方便阅读我添加了换行。
bootcmd=
run findfdt;
run mmcboot;
setenv mmcdev 1;
setenv bootpart 1:2;
run mmcboot;
run nandboot;
findfdt=
if test $board_name = A335BONE;
then
setenv fdtfile am335x-bone.dtb;
fi;
if test $board_name = A335BNLT;
then
setenv fdtfile am335x-boneblack.dtb;
fi;
if test $board_name = A33515BB;
then
setenv fdtfile am335x-evm.dtb;
fi;
if test $board_name = A335X_SK;
then
setenv fdtfile am335x-evmsk.dtb;
fi;
if test $fdtfile = undefined;
then
echo WARNING: Could not determine device tree to use;
fi;
board_name=A335BNLT
复制代码
首先是运行findfdt中的命令,目的是通过board_name来设置fdtfile,结果是fdtfile的值为am335x-boneblack.dtb。
mmcboot=
mmc dev ${mmcdev};
if mmc rescan;
then
echo SD/MMC found on device ${mmcdev};
if run loadbootenv;
then
echo Loaded environment from ${bootenv};
run importbootenv;
fi;
if test -n $uenvcmd;
then
echo Running uenvcmd ...;
run uenvcmd;
fi;
if run loadimage;
then
run mmcloados;
fi;
fi;
mmcdev=0
复制代码
"mmc dev 0"是将设备切换到0,通常有2个设备一个是SD卡,一个是eMMC。
loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}
loadaddr=0x80200000
bootenv=uEnv.txt
复制代码
这应该是从设备0的第1个分区装载uEnv.txt到地址0x80200000。
当默认的环境变量不符合要求时,可以用uEnv.txt设置新的环境变量。没有它也可以,先不用管,后面说。
importbootenv=echo Importing environment from mmc ...; env import -t $loadaddr $filesize
复制代码
这是把uEnv.txt中的环境变量导入到U-Boot的环境变量中。“filesize”没有指定。
loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
bootpart=0:2
bootdir=/boot
bootfile=zImage
复制代码
由于我没有“uenvcmd”这个环境变量,所以那个条件语句中的内容没有执行。我记着Arch Linux好像用了那个,那个变量应该在uEnv.txt中。
于是直接到了loadimage,这里和载入uEnv.txt是相似的,“0:2”的意思是设备0的第2个分区,而载入uEnv.txt时没有指定分区,就默认第1分区了。
loadimage的目的是将Linux内核载入内存。
mmcloados=
run mmcargs;
if test ${boot_fdt} = yes || test ${boot_fdt} = try;
then
if run loadfdt;
then
bootz ${loadaddr} - ${fdtaddr};
else
if test ${boot_fdt} = try;
then
bootz;
else
echo WARN: Cannot load the DT;
fi;
fi;
else
bootz;
fi;
复制代码
mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype}
console=ttyO0,115200n8
mmcroot=/dev/mmcblk0p2 ro
mmcrootfstype=ext4 rootwait
复制代码
这个就是设置bootargs这一个环境变量而已,用于向内核传递参数。
boot_fdt=try
loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
fdtaddr=0x80F80000
复制代码
之前载入了Linux内核,这里载入了设备树文件。
最后通过bootz后接2个地址就启动了系统。
总结如下
mmc dev 0;
load mmc 0:2 0x80200000 /boot/zImage
setenv bootargs concole=ttyO0,115200n8 root=mmcroot=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
load mmc 0:2 0x80F80000 /boot/am335x-boneblack.dtb
bootz 0x80200000 - 0x80F80000
复制代码
这是默认环境变量的行为。而我们的系统可能与其不同。这就要修改环境变量。
我知道有2种方式,一种是在U-Boot的命令行中通过命令修改,另一种就是通过uEnv.txt了。
这里介绍uEnv.txt的方式。先列出我uEnv.txt的内容,不用详细看,看我下面的说明。
bootfile=uImage
loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/dts/${fdtfile}
mmcloados=run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} =
try; then if run loadfdt; then bootm ${loadaddr} - ${fdtaddr}; else if
test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT;
fi; fi; else bootz; fi;
mmcroot=/dev/mmcblk0p2 rw
mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} init=/usr/lib/systemd/systemd
复制代码
一共6行,最后一行空白。
bootfile修改了内核名字,
loadfdt中只是在目录中加了“dts/”,
mmcloados主要是把bootz改成bootm。
mmcroot把只读改成了读写。
mmcargs只是在后面指定了init为systemd,也有其他方法,如init为指向systemd的软链接。
这里是从设备0启动系统,怎样知道自己的系统位于哪个设备呢,也许有某种约定,比如如果有SD卡,那么SD卡是0。
我不知道的话,可以在U-Boot的命令行中通过命令判断。如,
U-Boot# mmc list
OMAP SD/MMC: 0
OMAP SD/MMC: 1
复制代码
列出mmc设备。
U-Boot# mmc dev
mmc0 is current device
复制代码
显示当前是那个设备。
U-Boot# mmc part
Partition Map for MMC device 0 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 2048 131072 29942d7e-01 0c Boot
2 133120 15390720 29942d7e-02 83
复制代码
显示当前设备的分区信息。
U-Boot# ls mmc 0:1
100688 mlo
308232 u-boot.img
510 uenv.txt
3 file(s), 0 dir(s)
复制代码
列出设备0第1个分区“/”目录的文件,我没有指定,默认为“/”。
启动到U-Boot的时候,会看到
Hit any key to stop autoboot:0
复制代码
按下任意键则放弃了自动引导,从而进入了U-Boot的命令行。
在这里你可以手动进行接下来系统的引导。但是我不会。
虽然不会,但是用于板子上的系统有自动引导,
我们可以分析自动引导,来了解U-Boot是如何引导系统的。
在U-Boot的官网手册中看到了2个关键的环境变量和1个命令。
bootcmd: This variable defines a command string that is automatically executed
when the initial countdown is not interrupted.
This command is only executed when the variable bootdelay is also defined!
bootargs: The contents of this variable are passed to the Linux kernel as boot
arguments (aka "command line").
run - run commands in an environment variable
bootcmd中的命令就是出现“Hit any key to stop autoboot”提示后,不按任意键,会自动运行的命令。
bootargs是传递给Linux内核的参数。
run是运行环境变量中的命令,bootcmd中包含run命令。
所以分析引导过程要从bootcmd开始。
在U-Boot的命令行中输入printenv可显示所有的环境变量,我已经把相关的粘贴到了下面。
为方便阅读我添加了换行。
bootcmd=
run findfdt;
run mmcboot;
setenv mmcdev 1;
setenv bootpart 1:2;
run mmcboot;
run nandboot;
findfdt=
if test $board_name = A335BONE;
then
setenv fdtfile am335x-bone.dtb;
fi;
if test $board_name = A335BNLT;
then
setenv fdtfile am335x-boneblack.dtb;
fi;
if test $board_name = A33515BB;
then
setenv fdtfile am335x-evm.dtb;
fi;
if test $board_name = A335X_SK;
then
setenv fdtfile am335x-evmsk.dtb;
fi;
if test $fdtfile = undefined;
then
echo WARNING: Could not determine device tree to use;
fi;
board_name=A335BNLT
复制代码
首先是运行findfdt中的命令,目的是通过board_name来设置fdtfile,结果是fdtfile的值为am335x-boneblack.dtb。
mmcboot=
mmc dev ${mmcdev};
if mmc rescan;
then
echo SD/MMC found on device ${mmcdev};
if run loadbootenv;
then
echo Loaded environment from ${bootenv};
run importbootenv;
fi;
if test -n $uenvcmd;
then
echo Running uenvcmd ...;
run uenvcmd;
fi;
if run loadimage;
then
run mmcloados;
fi;
fi;
mmcdev=0
复制代码
"mmc dev 0"是将设备切换到0,通常有2个设备一个是SD卡,一个是eMMC。
loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}
loadaddr=0x80200000
bootenv=uEnv.txt
复制代码
这应该是从设备0的第1个分区装载uEnv.txt到地址0x80200000。
当默认的环境变量不符合要求时,可以用uEnv.txt设置新的环境变量。没有它也可以,先不用管,后面说。
importbootenv=echo Importing environment from mmc ...; env import -t $loadaddr $filesize
复制代码
这是把uEnv.txt中的环境变量导入到U-Boot的环境变量中。“filesize”没有指定。
loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
bootpart=0:2
bootdir=/boot
bootfile=zImage
复制代码
由于我没有“uenvcmd”这个环境变量,所以那个条件语句中的内容没有执行。我记着Arch Linux好像用了那个,那个变量应该在uEnv.txt中。
于是直接到了loadimage,这里和载入uEnv.txt是相似的,“0:2”的意思是设备0的第2个分区,而载入uEnv.txt时没有指定分区,就默认第1分区了。
loadimage的目的是将Linux内核载入内存。
mmcloados=
run mmcargs;
if test ${boot_fdt} = yes || test ${boot_fdt} = try;
then
if run loadfdt;
then
bootz ${loadaddr} - ${fdtaddr};
else
if test ${boot_fdt} = try;
then
bootz;
else
echo WARN: Cannot load the DT;
fi;
fi;
else
bootz;
fi;
复制代码
mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype}
console=ttyO0,115200n8
mmcroot=/dev/mmcblk0p2 ro
mmcrootfstype=ext4 rootwait
复制代码
这个就是设置bootargs这一个环境变量而已,用于向内核传递参数。
boot_fdt=try
loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
fdtaddr=0x80F80000
复制代码
之前载入了Linux内核,这里载入了设备树文件。
最后通过bootz后接2个地址就启动了系统。
总结如下
mmc dev 0;
load mmc 0:2 0x80200000 /boot/zImage
setenv bootargs concole=ttyO0,115200n8 root=mmcroot=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
load mmc 0:2 0x80F80000 /boot/am335x-boneblack.dtb
bootz 0x80200000 - 0x80F80000
复制代码
这是默认环境变量的行为。而我们的系统可能与其不同。这就要修改环境变量。
我知道有2种方式,一种是在U-Boot的命令行中通过命令修改,另一种就是通过uEnv.txt了。
这里介绍uEnv.txt的方式。先列出我uEnv.txt的内容,不用详细看,看我下面的说明。
bootfile=uImage
loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/dts/${fdtfile}
mmcloados=run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} =
try; then if run loadfdt; then bootm ${loadaddr} - ${fdtaddr}; else if
test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT;
fi; fi; else bootz; fi;
mmcroot=/dev/mmcblk0p2 rw
mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} init=/usr/lib/systemd/systemd
复制代码
一共6行,最后一行空白。
bootfile修改了内核名字,
loadfdt中只是在目录中加了“dts/”,
mmcloados主要是把bootz改成bootm。
mmcroot把只读改成了读写。
mmcargs只是在后面指定了init为systemd,也有其他方法,如init为指向systemd的软链接。
这里是从设备0启动系统,怎样知道自己的系统位于哪个设备呢,也许有某种约定,比如如果有SD卡,那么SD卡是0。
我不知道的话,可以在U-Boot的命令行中通过命令判断。如,
U-Boot# mmc list
OMAP SD/MMC: 0
OMAP SD/MMC: 1
复制代码
列出mmc设备。
U-Boot# mmc dev
mmc0 is current device
复制代码
显示当前是那个设备。
U-Boot# mmc part
Partition Map for MMC device 0 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 2048 131072 29942d7e-01 0c Boot
2 133120 15390720 29942d7e-02 83
复制代码
显示当前设备的分区信息。
U-Boot# ls mmc 0:1
100688 mlo
308232 u-boot.img
510 uenv.txt
3 file(s), 0 dir(s)
复制代码
列出设备0第1个分区“/”目录的文件,我没有指定,默认为“/”。
相关文章推荐
- usleep()和sleep()的区别
- 深入浅出谈数据挖掘zz
- Java ThreadLocal
- VC++ unique_ptr的使用例子
- linux awk命令详解---sql语句对等awk语句
- 全球域名注册商(国际域名)保有量及市场份额(6月6日)
- 用ruby写的一个网络爬虫程序
- [界面设计模式]_[观察者模式]
- Ubuntu 15.04 编译JDK7 HotSpot虚拟机
- Tuxedo英文全称
- 【最小生成树+子集枚举】Uva1151 Buy or Build
- Marshal.SecureStringToBSTR
- LeetCode之“动态规划”:Triangle
- [转载] tcp那些事2
- Aone新拉分支
- run as只有run configiations没有其他项
- Bean property 'manualPaperService' is not writable or has an invalid setter method. Did you mean 'ma
- swift NSNumber 转 Sting 遇到的问题
- java 修饰符判断
- C#:异步编程和线程的使用(.NET 4.5 )