busybox的移植

1、busybox源码下载
busybox是一个开源项目,版本差异不大,版本新旧无所谓。可以去www.busybox.net官方网站下载。

2、修改Makefile

  • ARCH = arm
  • CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin//arm-none-linux-gnueabi-

3、make menuconfig进行配置
参照如下的记录进行配置。

Busybox Settings--->
	Build Options--->
		[*]Build BusyBox as a static binary(no shared libs)

		
Busybox Library Tuning--->
	[*]vi-style line editing commands
	[*]Fancy shell prompts
	
	
Linux Module Utilities--->
	[ ]Simplified modutils
	[*]insmod
	[*]rmmod
	[*]lsmod
	[*]modprobe
	[*]depmod

	
Linux System Utilities--->[*]mdev
	[*]Support /etc/mdev.conf
	[*]Support subdirs/symlinks
	[*]Support regular expressions substitutions when renaming dev
	[*]Support command execution at device addition/removal
	[*]Support loading of firmwares

4、make 然后 make install

  • make编译,如果有错误解决之(去除某些文件的条件编译)
  • make install执行的时候其实是在执行busybox顶层目录下的一个目标install。默认安装在当前目录,修改安装目录需要在menuconfig中配置。

5、设置bootargs挂载添加了busybox移植的rootfs

  • 内核配置支持nfs启动;
  • 注意uboot的bootargs设置成:setenv bootargs root=/dev/nfs nfsroot=192.168.1.141:/root/porting_x210/rootfs ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC2,115200
  • 结果现象:挂载成功,执行/linuxrc(也就是busybox)成功,但是因为找不到/etc/init.d/rcS和/dev/tty2等文件所以一直在打印错误提示信息,但是其实有进入命令行。
1、配置网络部分,主要是使能CONFIG_IP_PNP以在2中能够看到Root file system on NFS选项
Networking support 
	Networking options 
		TCP/IP networking
				IP: kernel level autoconfiguration
					[*] IP: DHCP support
					[*] IP: BOOTP support
					
2、配置开启nfs服务
File systems  --->	
	Network File Systems  --->
		<*> NFS client support 
		[*] NFS client support for NFS version 3                                  [*] NFS client support for the NFSv3 ACL protocol extension 
		[*] NFS client support for NFS version 4 (EXPERIMENTAL) 
		[*] NFS client support for NFSv4.1 (DEVELOPER ONLY) 
		[*] Root file system on NFS  
					
3、在uboot中设置如下启动参数(IP根据实际使用更改)
setenv bootargs root=/dev/nfs nfsroot=192.168.1.141:/root/porting_x210/rootfs/rootfs ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off  init=/linuxrc console=ttySAC2,115200 

添加/etc/inittab

添加一个典型的inittab。

#first:run the system script file
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:-/sbin/reboot
#umount all filesystem
::shutdown:/bin/umount -a -r
#restart init process
::restart:/sbin/init
  • 将提供的典型的inittab文件复制到制作的rootfs的根目录下的/etc/目录下;
  • 再次启动内核挂载这个rootfs,就可以进入了控制台命令行。当前就是一个制作的最小的rootfs;
    在这里插入图片描述
    相关inittab格式解析可参考:
    busybox下inittab初始化脚本格式分析
    /etc/inittab文件

主要关注:
最重要的是action和process。action是一个条件/状态,process是一个可被执行的程序的pathname。合起来的意思就是:当满足action的条件时就会执行process这个程序。
分析busybox的源代码就会发现(在busybox/init/init.c/init_main函数中),busybox(init进程)最终会进入一个死循环,在这个死循环中去反复检查是否满足各个action的条件,如果某个action的条件满足就会去执行对应的process。

添加/etc/init.d/rcS

添加一个典型的rcS。

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin

runlevel=S
prevlevel=N

umask 022

export PATH runlevel prevlevel

mount -a

echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

/bin/hostname -F /etc/sysconfig/HOSTNAME

ifconfig eth0 192.168.1.10

rcS内容解析

rcS是一个脚本文件,在init进程(busybox)启动时解析inittab文件中的sysinit这个action时要去执行的一个程序。因为sysinit被放在最前面,因此rcS可以说是最先执行的配置脚本。

1)导出三个环境变量:PATH、runlevel(运行等级,S就是single user mode单用户模式)、prevlevel;
2)umask是linux的一个命令,作用是设置创建文件时的默认权限;
3)mount -a,是挂载所有的应该被挂载的文件系统,在busybox中mount -a时busybox会去查找一个文件/etc/fstab文件,这个文件按照一定的格式列出来所有应该被挂载的文件系统(包括了虚拟文件系统);
4)mdev,mdev是udev的嵌入式简化版本,udev/mdev是用来配合linux驱动工作的一个应用层的软件,udev/mdev的工作就是配合linux驱动生成相应的/dev目录下的设备文件。效果:在rcS文件中没有启动mdev的时候,/dev目录下启动后是空的;在rcS文件中添加上mdev有关的2行配置项后,再次启动系统后发现/dev目录下生成了很多的设备驱动文件。
5)/bin/hostname -F /etc/sysconfig/HOSTNAME,来指定了一个主机名配置文件HOSTNAME
6)自定义的一些shell命令,例如ifconfig等。

/etc/fstab文件如下:

# /etc/fstab: static file system information.
#
# Use 'vol_id --uuid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# 	<file system> 	<mount point> 	<type> 	<options> 	<dump> 	<pass>
	proc 			/proc 			proc 	defaults 	0 		0
	sysfs 			/sys 			sysfs 	defaults 	0 		0
	tmpfs 			/var 			tmpfs 	defaults 	0 		0
	tmpfs 			/tmp 			tmpfs 	defaults 	0 		0
	tmpfs 			/dev 			tmpfs 	defaults 	0 		0

rcS实际测试

1、发现rcS文件明明存在但是却提示不存在,问题原因就是rcS文件在windows下创建的,行尾换行符为’\r\n’,多了点东西。但是因为ubuntu中的vi对行尾做了优化,所以在ubuntu中是看不出来多了东西的。但是在securecrt下一看就发现每一行末尾多出来了一个^M。

2、umask测试
(1)umask是022的时候,默认touch创建一个文件的权限是644
(2)umask是044的时候,默认touch创建一个文件的权限是622
(3)umask是444的时候,默认touch创建一个文件的权限是222
总结:umask的规律就是:umask值和默认创建文件的权限值加起来是666.

3、mount测试
(1)挂载时全部出错:
mount: mounting proc on /proc failed: No such file or directory
mount: mounting sysfs on /sys failed: No such file or directory
mount: mounting tmpfs on /var failed: No such file or directory
mount: mounting tmpfs on /tmp failed: No such file or directory
mount: mounting tmpfs on /dev failed: No such file or directory
(2)原因是因为根文件系统中找不到挂载点。解决方案就是自己在制作的rootfs根目录下创建这些挂载点目录即可。
(3)验证是否挂载成功,可以看挂载时输出信息;还可以启动后去看proc和sys文件夹,如果有文件出现则证明挂载成功了,如果没东西就证明失败了。

profile文件和用户登录

添加一个典型的profile文件。

# Ash profile
# vim: syntax=sh

# No core files by default
ulimit -S -c 0 > /dev/null 2>&1

USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]\# '
PATH=$PATH

HOSTNAME=`/bin/hostname`

export USER LOGNAME PS1 PATH

profile文件工作原理是:profile文件也是被busybox(init进程)自动调用的,所以是认名字的。

添加了之后可以显示主机名hostname了,命令行提示符前面显示:[@x210 ]#
登录用户名没显示出来,原因是直接进入了命令行而没有做登录。等我们添加了用户登录功能,并且成功登陆后这个问题就能解决。

添加登录界面

因为之前intttab中有一个配置项 ::askfirst:-/bin/sh,这个导致系统启动后就去执行/bin/sh,从而出现命令行。这样的安排就会直接进入命令行而不会出现登录界面。
因此,要出现登录界面,就不能直接执行/bin/sh,而应该执行一个负责出现登录界面并且负责管理用户名和密码的一个程序。busybox中也集成了这个程序(就是/bin/login和/sbin/gettty)。

1、在inittab中修改,去掉/bin/sh,换上/bin/login,则系统启动后出现登录界面。
2、添加passwd和shadow文件,直接复制ubuntu系统中的/etc/passwd和/etc/shadow文件到当前制作的rootfs目录下,然后再做修改即可。

  • linux系统中用来描述用户名和密码的文件是passwd和shadow文件,这两个文件都在etc目录下。passwd文件中存储的是用户的密码设置,shadow文件中存储的是加密后的密码。
  • /etc/passwd和/etc/shadow修理好后,shadow中默认root用户的密码口令,就是ubuntu中root用户的密码。
  • busybox中因为没有普通用户,所以默认root用户如果加密口令是空的则默认无密码直接登录。等我们登陆了之后还是可以用passwd root给root用户设置密码。如何重置密码?用其他系统(WindowsPE系统或者ubuntu的单用户模式等)来引导启动,启动后挂载到我们的硬盘上,然后找到/etc/shadow文件,去掉密文密码后保存。然后再重启系统后密码就没了。

关于这两个文件解析,详见:Linux 下/etc/passwd文件详解

动态链接库的拷贝

可以尝试写一个hello world程序,因为要运行在开发板中,所以要使用交叉编译。发现:
静态链接:arm-linux-gcc hello.c -o hello_satic -static的程序是可以运行的,但是动态链接(不加-static编译)的程序就不能运行,原因是/lib中还没有拷贝动态链接库,导致程序运行时需要链接的动态库找不到。

1、复制动态链接库到roots/lib目录下(动态链接库就在交叉编译工具链的所在的目录周围,需要找一下);
2、strip去掉库中符号信息;

开机自启动

开机自启动的实现原理就是在开机会自动执行的脚本rcS中添加上执行某个程序的语句代码即可。
为了避免程序运行时占用当前的控制台,可以让程序后台运行: ./xxx &

制作ext2格式的镜像并烧录

(1)制作ext2格式的rootfs
dd if=/dev/zero of=rootfs.ext2 bs=1024 count=10240
losetup /dev/loop1 rootfs.ext2
mke2fs -m 0 /dev/loop1 10240
mount -t ext2 /dev/loop1 ./ext2_rootfs/
(2)向./rootfs中复制内容,用cp …/rootfs/* ./ -rf
(3)清理退出
umount /dev/loop1
losetup -d /dev/loop1
(4)使用fastboot烧录制作好的rootfs.ext2到开发板inand中
fastboot flash system rootfs.ext2

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐