Bootloader之BareBox 之路(3)--Env(ironment)

上篇讲到start_barebox在执行死循环的shell之前会调用environment,这次来分析一下这些env。

 

代码
 
   
1 if (envfs_load( " /dev/env0 " , " /env " )) {
2 #ifdef CONFIG_DEFAULT_ENVIRONMENT
3 printf( " no valid environment found on /dev/env0. "
4 " Using default environment\n " );
5 envfs_load( " /dev/defaultenv " , " /env " );
6   #endif
7 }
8   #endif
9 printf( " running /env/bin/init...\n " );
10
11 if ( ! stat( " /env/bin/init " , & s)) {
12 run_command( " source /env/bin/init " , 0 );
13  

首先程序去读取/dev/env0到/env,正常情况下/dev/env0放的是一个(类似)压缩文件,envfs_load会对它做校验。毫无疑问,初始启动时肯定是找不到这个文件的,所以接着读取/dev/defaultenv到/env (loader跑起来后执行saveenv就把/env的东西打包到/dev/env0去了)。然后执行/env/bin/init。

 

接下去我们分析一下/env/bin/init即/dev/defaultenv/bin/init。打开barebox下的default/bin,找到init文件:

bin/init
 
   
1 # !/bin/sh
2  
3 PATH =/ env / bin
4 export PATH
5
6 . / env / config
7   if [ - e / dev / nor0 ]; then
8 addpart / dev / nor0 $nor_parts
9 fi
10
11   if [ - e / dev / disk0 ]; then
12 addpart / dev / disk0 $disk_parts
13 fi
14
15   if [ - e / dev / nand0 ]; then
16 addpart / dev / nand0 $nand_parts
17
18 # Uh, oh, hush first expands wildcards and then starts executing
19   # commands. What a bug!
20   source / env / bin / hush_hack
21 fi
22
23 if [ -f / env / bin / init_board ]; then
24 / env / bin / init_board
25 fi
26
27 echo
28 echo - n " Hit any key to stop autoboot: "
29 timeout - a $autoboot_timeout
30 if [ $? != 0 ]; then
31 echo
32 update - h
33 echo
34 exit
35 fi
36
37 boot
38

上面第6行. /env/config 相当于c语言中的include,是把/env/config文件包含进来,config文件的分析见下面。

上面第7行判断/dev/nor0是否存在,存在就执行第8行addpart命令,对nor0按照变量nor_parts的设定进行分区。addpart是一个barebox命令,可以在源代码里找到,以下barebox命令同。

上面第15行判断/dev/nand0是否存在,存在就执行16行对nand0按照变量nand_parts的设定进行分区,并执行source /env/bin/hush_hack (这里再加路径是否多余了?),hush_hack里就一句话" nand -a /dev/nand0.* ",其实是因为hush的一个bug不得不另外写一个文件(具体是否有这bug不明)。" nand -a /dev/nand0.* " 执行nand命令,为每个nand0的分区对应的创建一个bb(bad block aware)设备。

上面23行如果/env/bin/init_board存在,就执行它。现在是不存在,所以无视。

上面29行执行shell timeout,如果timeout不到0的话,就执行update -h,见下面对update文件的分析。如果timeout到0的话,就执行boot,见下面boot文件的分析。

 

/env/config是barebox下arch/arm/board/{myboard}/env/config的一个复制:

env/config
 
   
1 # !/bin/sh
2
3 machine = pcm038
4 eth0.serverip =
5 user =
6
7 # use 'dhcp' to do dhcp in barebox and in kernel
8 # use 'none' if you want to skip kernel ip autoconfiguration
9 ip = dhcp
10
11 # or set your networking parameters here
12 # eth0.ipaddr=a.b.c.d
13 # eth0.netmask=a.b.c.d
14 # eth0.gateway=a.b.c.d
15 # eth0.serverip=a.b.c.d
16
17 # can be either 'net', 'nor' or 'nand'
18 kernel_loc = net
19 # can be either 'net', 'nor', 'nand' or 'initrd'
20 rootfs_loc = net
21
22 # can be either 'jffs2' or 'ubifs'
23 rootfs_type = ubifs
24 rootfsimage = root - $machine . $rootfs_type
25
26 # The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
27 kernelimage_type = zimage
28 kernelimage = zImage - $machine
29 # kernelimage_type=uimage
30 # kernelimage=uImage-$machine
31 # kernelimage_type=raw
32 # kernelimage=Image-$machine
33 # kernelimage_type=raw_lzo
34 # kernelimage=Image-$machine.lzo
35
36 if [ - n $user ]; then
37 kernelimage = " $user " - " $kernelimage "
38 nfsroot = " $eth0.serverip:/home/$user/nfsroot/$machine "
39 rootfsimage = " $user " - " $rootfsimage "
40 else
41 nfsroot = " $eth0.serverip:/path/to/nfs/root "
42 fi
43
44 autoboot_timeout = 3
45
46 bootargs = " console=ttymxc0,115200 "
47
48 nor_parts = " 256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root) "
49 rootfs_mtdblock_nor = 3
50
51 nand_parts = " 256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root) "
52 rootfs_mtdblock_nand = 7
53
54 # set a fancy prompt (if support is compiled in)
55 PS1 = " \e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
56
57

这个文件定义了一堆变量,注意52行,如果没有nor_parts的话,那么rootfs_mtdblock_nand(在nand_parts的root,从0~3)就等于3了。大部分变量都为init文件和boot文件所用。

最后一句PS1可以在hush.c中的getprompt看到,具体就是跟hyperterminal配合把命令提示字符串barebox@<board_name>的barebox@改成了绿色,把board_name改成了红色。

 

update文件提供了组合了下载,擦除flash,烧写和检查等的一个update命令,如果输入的参数是h的话就调用(见init)就调用_update_help,打印update的用法,如果参数输入正确的话,调用_update文件进行实际的下载烧写动作(update文件主要是对参数做判断)。

 

boot文件建立起bootargs,然后boot系统:

/bin/boot
 
   
1 # !/bin/sh
2
3 . / env / config
4
5 if [ x $1 = xnand ]; then
6 rootfs_loc = nand
7 kernel_loc = nand
8 elif [ x $1 = xnor ]; then
9 rootfs_loc = nor
10 kernel_loc = nor
11 elif [ x $1 = xnet ]; then
12 rootfs_loc = net
13 kernel_loc = net
14 fi
15
16 if [ x $ip = xdhcp ]; then
17 bootargs = " $bootargs ip=dhcp "
18 elif [ x $ip = xnone ]; then
19 bootargs = " $bootargs ip=none "
20 else
21 bootargs = " $bootargs ip=$eth0.ipaddr::$eth0.gateway:$eth0.netmask::: "
22 fi
23
24
25 if [ x $rootfs_loc = xnet ]; then
26 bootargs = " $bootargs root=/dev/nfs nfsroot=$nfsroot,v3,tcp noinitrd "
27 elif [ x $rootfs_loc = xinitrd ]; then
28 bootargs = " $bootargs root=/dev/ram0 rdinit=/sbin/init "
29 else
30 if [ x $rootfs_loc = xnand ]; then
31 rootfs_mtdblock = $rootfs_mtdblock_nand
32 else
33 rootfs_mtdblock = $rootfs_mtdblock_nor
34 fi
35
36 if [ x $rootfs_type = xubifs ]; then
37 bootargs = " $bootargs root=ubi0:root ubi.mtd=$rootfs_mtdblock "
38 else
39 bootargs = " $bootargs root=/dev/mtdblock$rootfs_mtdblock "
40 fi
41
42 bootargs = " $bootargs rootfstype=$rootfs_type noinitrd "
43 fi
44
45 if [ - n $nor_parts ]; then
46 mtdparts = " ${mtdparts}physmap-flash.0:${nor_parts}; "
47 fi
48
49 if [ - n $nand_parts ]; then
50 mtdparts = " ${mtdparts}${nand_device}:${nand_parts}; "
51 fi
52
53 if [ - n $mtdparts ]; then
54 bootargs = " ${bootargs} mtdparts=${mtdparts} "
55 fi
56
57 if [ ! - e / dev / ram0.kernelraw ]; then
58 # arm raw kernel images are usually located at sdram start + 0x8000
59 addpart dev / ram0 8M @ 0x8000 (kernelraw)
60 fi
61
62 if [ ! - e / dev / ram0.kernel ]; then
63 # Here we can safely put the kernel without risking of overwriting it
64 # while extracting
65 addpart dev / ram0 8M @ 8M(kernel)
66 fi
67
68 if [ x $kernel_loc = xnet ]; then
69 if [ x $ip = xdhcp ]; then
70 dhcp
71 fi
72 if [ $kernelimage_type = uimage ]; then
73 netload = " /dev/ram0.kernel "
74 elif [ $kernelimage_type = zimage ]; then
75 netload = " /dev/ram0.kernel "
76 elif [ $kernelimage_type = raw ]; then
77 netload = " /dev/ram0.kernelraw "
78 elif [ $kernelimage_type = raw_lzo ]; then
79 netload = " /dev/ram0.kernel "
80 else
81 echo " error: set kernelimage_type to one of 'uimage', 'zimage', 'raw' or 'raw_lzo' "
82 exit 1
83 fi
84 tftp $kernelimage $netload || exit 1
85 kdev = " $netload "
86 elif [ x $kernel_loc = xnor ]; then
87 kdev = " /dev/nor0.kernel "
88 elif [ x $kernel_loc = xnand ]; then
89 kdev = " /dev/nand0.kernel.bb "
90 else
91 echo " error: set kernel_loc to one of 'net', 'nand' or 'nor' "
92 exit 1
93 fi
94
95 echo " booting kernel of type $kernelimage_type from $kdev "
96
97 if [ x $kernelimage_type = xuimage ]; then
98 bootm $kdev
99 elif [ x $kernelimage_type = xzimage ]; then
100 bootz $kdev
101 elif [ x $kernelimage_type = xraw ]; then
102 if [ $kernel_loc != net ]; then
103 cp $kdev / dev / ram0.kernelraw
104 fi
105 bootu / dev / ram0.kernelraw
106 elif [ x $kernelimage_type = xraw_lzo ]; then
107 unlzo $kdev / dev / ram0.kernelraw
108 bootu / dev / ram0.kernelraw
109 fi
110

boot的执行有两种,一种是timeout后init里的调用,无输入参数,这时5~14行就没有意义,那些变量就采取config里的定义。一种是没到timeout就按键进入了barebox,这时可以对boot加上参数来改变那些变量。

上面16~55行重新设定了内核启动参数bootargs。

上面57~60行添加了Linux内核运行的分区kernelraw,大小为8M,位于/dev/ram0即SDRAM的0x8000偏移处。

上面62~66行添加了Linux解压缩的一个分区kernel,大小为8M,位于/dev/ram0即SDRAM的8MB=0x80 0000偏移处。(跟kernelraw重合了0x8000即32KB的空间,不过Linux内核肯定小于8M-32K,所以无所谓)

上面68~93行设定变量kdev,如果是从网络下载的话,首先执行dhcp,然后用tftp下载内核到kernel分区(如果内核未经压缩,那就直接下载到kernelraw),然后再把kdev设定为/dev/kernelraw或者/dev/kernel或者/dev/nor0.kernel或者/dev/nand0.kernel.bb。

上面97~109判断kernel类型,如果是压缩的就先解压,最后都是bootu /dev/ram0.kernalraw

 

 

附1:Env里用到的barebox命令:

代码
 
   
1 addpart(do_addpart)
2 bootm(do_bootm)
3 bootu(do_bootu)
4 bootz(do_bootz)
5 cp(do_cp)
6 crc32(do_crc)
7 dhcp(do_dhcp)
8 echo(do_echo)
9 erase(do_flerase)
10 exit(do_exit)
11 export(do_export)
12 getopt(do_getopt)
13 loadb(do_load_serial_bin)
14 nand(do_nand)
15 ping(do_ping)
16 protect(do_protect)
17 source(do_source)
18 tftp(do_tftp)
19 timeout(do_timeout)
20 unprotect(do_protect)
21 unlzo(do_unlzo)

 

转载于:https://www.cnblogs.com/kubtu/archive/2010/12/07/1898951.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值