initramfs根文件系统移植

基于ubuntu14.04,fl2440开发板的根文件系统移植

所谓根文件系统首先是内核启动时所mount的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。

文件系统的制作其实并没有想像中那么难。一个基本的文件系统应该包括: busybox (提供 shell 命令集)、配置文件(用来初始化和布局你的文件系统)、设备文件(如果是用 devfs 的话这个就免了)、必要的库文件系统(如果 busybox 是静态编译的话,那根本不用为 busybox 用到的库文件而烦。

根文件系统树制作

├── apps					nandflash apps分区挂载点,用来存放应用程序
├── bin						系统基本命令
├── data					nandflash data分区挂载点,用来存放数据
├── dev						系统设备节点所在路径
├── etc						系统配置文件所在路径
│   └── init.d				系统初始化、启动程序脚本
├── info						nandflash info分区挂载点,用来存放设备信息
├── lib						系统动态库路径
│   └── modules		
│       └── 3.0.0			linux内核驱动模块需要该路径
├── mnt						系统挂载点
│   ├── mmc				SD卡挂载点
│   └── usb				U盘挂载点
├── proc					linux proc文件系统挂载点
├── root						root用户home
├── sbin					系统管理命令
├── sys						linux sys文件系统挂载点
├── tmp						linux tmp文件系统挂载点
├── usr						
│   ├── bin					用户基本命令路径
│   ├── lib					用户动态库文件
│   └── sbin				用户管理命令路径
└── var						系统日志等文件存放路径

安装动态库

开发板上的所有程序都是靠交叉编译器编译的,所以要链接相应的动态库,就得把交叉编译器的动态库拷到相应的路径下
但是拷贝过程中发现很多的链接库失效了,需要重新建立链接
所以编写一个脚本把失效的链接都恢复

#!/bin/bash
	# find all the invalid symlink file and remove "./" before it
	for sf in `find -L -type l | cut -d'/' -f2` ; do
	# parser and get symlink target file name
	file=`ls -l $sf | awk -F '/' '{ print $NF }'`
	# remove invalid symlink file and generate new one
	rm -f $sf && ln -s $file $sf
done

这样就把创建新的链接文件并替换掉坏掉的文件。

安装busybox

BusyBox 是一个集成了一百多个最常用Linux命令和工具的软件,如ls、cat、ifconfig、vim、grep、sed、awk、find、mount、telnet等。有些人将
BusyBox 称为 Linux 工具里的瑞士军刀,简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令。我们通过下载busybox源码、
配置编译并安装它就会提供这些Linux的基本命令的实现,它们将会被安装到根文件系统树的 bin、sbin、usr/bin、usr/sbin等路径下。
busybox源码:https://busybox.net/downloads/busybox-1.27.1.tar.bz2
同样我们也需要对busybox进行配置
busybox settings —>下
在这里插入图片描述

在这里插入图片描述
Linux System Utilities —>下
在这里插入图片描述
Coreutils —>下
在这里插入图片描述
Print Utilities —>
Mail Utilities —>
这两项是关于打印和邮箱的一些配置 用不着可以全部不用选。
在我们自己的rootfs树下面建立软链接ln -s /bin/busybox init
在这里插入图片描述
这是后就有就有命令链接着busybox到我们的相应的路径下去了

创建dev下的设备节点

sudo mknod -m666 null c 1 3
sudo mknod -m666 console  c 5 1
sudo mknod -m666 ttyS0 c 4 64

在这里插入图片描述
这些是系统启动必须的设备节点。

创建var路径下文件

var

ln -s /tmp var/lock
ln -s /tmp var/log
ln -s /tmp var/run
ln -s /tmp var/tmp

在这里插入图片描述

创建etc路径下文件

创建etc/inittab文件

该文件配置了在init启动程序后要启动那些程序
vim etc/inittab 这里文件的权限是775 但是我写入不了 所以果断把普通用户加入到root组中 usermod -G root xiaobaicai
这样就可以编辑了

# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# id == tty to run on, or empty for /dev/console.
# If specified, then /dev/$id device must exist
# runlevels == ignored, busybox doesn't support it
# action == one of sysinit, respawn, askfirst, wait, and once
# process == program to run
# Startup the system
# mount all the file systems specified in /etc/fstab
::sysinit:/bin/mount -a
# Use mdev to auto generate device nod and auto mount SD card and USB storage
::sysinit:/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
::sysinit:/sbin/mdev -s
#make shm, pts support
::sysinit:/bin/mkdir -p /dev/pts
::sysinit:/bin/mkdir -p /dev/shm
::sysinit:/bin/mount -t devpts devpts /dev/pts
#Set hostname
null::sysinit:/bin/hostname -F /etc/hostname
#Enable console logon
null::respawn:/sbin/getty -L ttyS0 115200 vt100
# now run any rc scripts, which used to start other application
null::wait:/etc/init.d/rcS
# system daemon
null::respawn:/sbin/syslogd -n
null::respawn:/sbin/klogd -n
# Stuff to do before rebooting
null::shutdown:/bin/killall klogd
null::shutdown:/bin/killall syslogd
null::shutdown:/bin/umount -a -r

保存退出

创建etc/fstab文件

Linux下的mount -a命令将自动挂载/etc/fstab文件中指定的所有需要系统自动挂载的文件。在/etc/inittab中会使用该命令在上电时自动挂载相应的文件
系统,这里面主要是挂载一些伪文件系统,这些伪文件系统主要是导出Linux内核运行的相关信息,如比较重要的tmpfs、sysfs、proc文件系统等。

  1 #/etc/fstab: static file system information.
  2 #
  3 #<file system> <mount pt>       <type> <options> <dump> <pass>
  4 /dev/root       /               ext2    rw,noauto   0       1
  5 proc            /proc           proc    defaults    0       0
  6 usbfs           /proc/bus/usb   usbfs   defaults    0       0
  7 tmpfs           /dev            tmpfs   defaults    0       0
  8 ramfs           /tmp            ramfs   defaults    0       0
  9 sysfs           /sys            sysfs   defaults    0       0                                                               
创建hostname文件

vim etc/hostname
xiaobaicaiFl2440

创建系统启动脚本

系统所有的启动脚本我们都将放在/etc/init.d路径下,接下来我们将创建这些系统启动脚本:
脚本一:rcS
/etc/inittab脚本会使用命令/etc/init.d/rcS启动所有其它的应用程序,下面创建etc/rcS脚本,该脚本将执行/etc/init.d/下所有文件名以S开头且后面紧
跟至少包括2个字符的文件。

  1 #!/bin/sh
  2 # Start all scripts in /etc/init.d, executing them in numerical order.
  3 for i in /etc/init.d/S??* ; do
  4 $i
  5 done

chmod a+x rcS
脚本二:S10_network
这个脚本可以实现上机初始化网卡,自动设置网卡IP地址,这个文件是一个S开头后面字符不少于两个的脚本文件

  1 #!bin/sh
  2 ifconfig eth0 192.168.1.250 netmask 255.255.255.0 up

chmod a+x S10_network
脚本三:S99_rcsApp
今后我们很多应用程序将会存放在/apps分区下,有时我们希望这些应用程序的启动脚本也存放在该分区下以便于管理。这时我们可以参考rcS脚本的实现
机制,让它也执行在/apps/etc下的所有启动脚本。

  1 #!bin/sh
  2 # Start all scripts in /apps/etc/init.d, executing them in numerical order.
  3 for i in /apps/etc/init.d/S??* ; do
  4 $i
  5 done

chmod a+x S99_rcsApp

创建 shell配置文件

在linux操作系统中,我们可以通过配置~/.bash_profile和 ~/.bashrc来修改shell的配置文件,即修改PATH、LD_LIBRARY_PATH
vim profile

  1 # Busybox Shell(ash) configure file
  2 export PATH=/bin:sbin:/usr/bin:/usr/sbin:/apps/bin:/apps/tools
  3 export PS1='\w >: '
  4 export USER=`id -un`
  5 export LOGNAME=$USER
  6 export HOSTNAME=`/bin/hostname`
  7 export HISTSIZE=500
  8 export HISTFILESIZE=500
  9 export PAGER='/bin/more'
 10 export EDITOR='/bin/vi'
 11 export INPUTRC=/etc/inputrc
 12 export LD_LIBRARY_PATH=/lib:/usr/lib:/apps/lib
 13 export network_cfg_dir=/apps/etc/network
 14 
 15 ### Some alias command
 16 alias vim='vi'
 17 alias ll='ls -l'
 18 alias l.='ls -d .*'
 19 alias df='df -h'
创建linux登录文件

Linux系统中的登录帐号信息保存在/etc/group、/etc/passwd和/etc/shadow文件中。
/etc/group中是用户组信息
/etc/passwd中是用户的信息,但是用户密码的信息加密放在/etc/shadow中
/etc/group
vim group
groupname:password:gid:members
第一个字段为用户组名称;
第二个字段为用户组密码,当为x时密码是映射到/etc/shadow中的,是非逆的;
第三个字段为GID,及组号,为正整数或0,0被付于了root用户组;系统通常会预留一些较靠前的GID给系统虚拟用户之用,每个系统预留的GID都
不同,一般普通用户的GID从500开始;
第四个字段为用户列表,每个用户间用逗号分隔;

root:x:0:root

/etc/passwd
vim passwd
username:password:uid:gid:fullname:homedir:shell
第一个字段为登录用户名
第二个字段为密码,这里设置为x表示密码被映射到/etc/shadow文件中
第三个字段为用户ID(UID)
第四个字段为用户所属组ID(GID)
第五个字段为用户名全称
第六个字段为用户根目录
第七个字段为用户所用shell的类型
Unix系统最初是用明文保存密码的,后来由于安全的考虑,采用crypt()算法加密密码并存放在/etc/passwd文件。现在,由于计算机处理能力的提高,使
密码破解变得越来越容易。/etc/passwd文件是所有合法用户都可访问的,大家都可互相看到密码的加密字符串,这给系统带来很大的安全威胁。现代的
Unix系统使用影子密码系统,它把密码从/etc/passwd文件中分离出来,真正的密码保存在/etc/shadow文件中,shadow文件只能由超级用户访问。这样
入侵者就不能获得加密密码串,用于破解。使用shadow密码文件后,/etc/passwd文件中所有帐户的password域的内容为"x",如果password域的内容
为"*",则该帐号被停用。

root:x:0:0:root:/:/bin/sh

/etc/shadow/
/etc/shadow文件保存了相应帐号的密文,这个文件内容不能直接创建。如果我们想在嵌入式Linux系统中设置root的登录密码为123456,则我们先在自
己的Linux服务器或虚拟机上修改root密码为123456,然后再将Linux服务器或虚拟机上的/etc/shadow文件里root帐号的密码密文部分拷贝出来,创建根
文件系统树里的etc/shadow时将密文部分用这个密文替换。这个过程做完后记得将自己的Linux服务器或虚拟机的root密码还原回去。
这是我的123456密文
$6$0MXGlHzK$7p2Kdf1nqNEj4KX6o/mI1PZYiaDX/cXP55MgM0dxDFWM91Kw3wc2fRRNW8xwwAWad79b64J5x9cncNy8.vhZP0
vim shadow
加上去

root:$6$0MXGlHzK$7p2Kdf1nqNEj4KX6o/mI1PZYiaDX/cXP55MgM0dxDFWM91Kw3wc2fRRNW8xwwAWad79b64J5x9cncNy8.vhZP0:0:0:99999:7:::

username:password:last_change:min_change:max_change:warm:failed_expire:expiration:reserved
每个字段意义
第一字段:用户名(也被称为登录名),在/etc/shadow中,用户名和/etc/passwd 是相同的,这样就把passwd 和shadow中用的用户记录联系在
一起;这个字段是非空的;
第二字段:密码加密后的密文,这个字段是非空的;
第三字段:上次修改密码的时间;这个时间是从1970年01月01日算起到最近一次修改口令的时间间隔(天数);
第四字段:两次修改密码间隔最少的天数;如果这个字段的值为空,帐号永久可用;
第五字段:两次修改密码间隔最多的天数;如果这个字段的值为空,帐号永久可用;
第六字段:提前多少天警告用户密码将过期;如果这个字段的值为空,帐号永久可用;
第七字段:在密码过期之后多少天禁用此用户;如果这个字段的值为空,帐号永久可用;
第八字段:用户过期日期;此字段指定了用户作废的天数(从1970年的1月1日开始的天数),如果这个字段的值为空,帐号永久可用;
第九字段:保留字段,目前为空,以备将来发展之用;

创建linux其他文件

/etc/resolv.conf
该文件用来设置Linux下DNS服务器

nameserver 114.114.114.114
nameserver 4.2.2.2

/etc/hosts
该文件存放本机地址

127.0.0.1			localhost

/etc/TZ
该文件配置了系统时区

MST7MDT

/etc/issue
该文件存放了在console上登录系统时提示的警告信息

Copyright (C) 2012 LingYun I.o.T Studio< iot-yun.com >
Default Logon Username: root Password: 123456

至此Linux根文件系统树所需要的基本文件都已经有了,接下来我们可以使用Linux内核启动这个根文件系统。

内核启动initramfs文件系统

nitramfs是Linus开发的一种基于内存的根文件系统,在编译Linux内核的时候,它会直接把根文件系统树打包进内核的镜像文件中(zImage),这也意味
着该镜像文件同时包含了Linux内核和根文件系统。因为根文件系统是内核打包进去的,所以内核自己知道根文件系统的位置,这样u-boot也就不需要通过
bootargs参数告诉内核根文件系统的信息,此外也不需要额外烧录根文件系统镜像文件,如ubifs、yaffs2、jffs2等。在今后做其他根文件系统的时候,请
务必在内核中禁用initramfs,否则Linux内核将优先使用initramfs启动了。
因为initramfs是基于内存的根文件系统,所以大家在开发板上对根文件系统里的任何文件的操作,包括创建、删除、修改在重启后都会丢失。因此如果
想要更改根文件系统里的文件,必须修改根文件系统树,然后重新编译Linux内核并使用u-boot重新烧录。
Linux内核使用initramfs启动,只需要在make menuconfig作下面修改,然后重新编译即可。
General setup —>
在这里插入图片描述
这样把initramfs编译到内核中,会导致最后生成的uImage会比平时大许多,所以得修改uboot的读取参数,不然uboot会出现校验失败
Device Drivers —>
Block devices —>
在这里插入图片描述
至此就完成了我们的配置工作,make编译后并用mkimage修改我们的zimage镜像文件为uimage(linuxrom-s3c2440.bin)后,就可以进行烧录了。
在这里插入图片描述
在uboot调试模式下把我们的镜像文件下载进去并bootm启动他,内核和根文件系统就被启动了。

猜你喜欢

转载自blog.csdn.net/qq_40215005/article/details/89608862