linux根文件系统编译和移植过程
一、概念根文件系统:系统运行所必须依赖的一些文件(比如脚本、库、配置文件、命令…),本质就是目录和文件。根文件系统镜像:将根文件系统按照某种格式进行打包压缩后生成的单个文件 rootfs-----> ramdisk.img文件系统:一种管理和访问磁盘的软件机制,不同文件系统管理和访问磁盘的机制不同二、移植根文件系统的工具 —> busybox1、短小精悍2、版本更新较快,版本之间差异不
一、概念
根文件系统:系统运行所必须依赖的一些文件
(比如脚本、库、配置文件、命令…),本质就是目录和文件。
根文件系统镜像:将根文件系统按照某种格式进行
打包压缩后生成的单个文件 rootfs-----> ramdisk.img
文件系统:一种管理和访问磁盘的软件机制,
不同文件系统管理和访问磁盘的机制不同
二、移植根文件系统的工具 —> busybox
1、短小精悍
2、版本更新较快,版本之间差异不大
三、如何获取busybox
https://busybox.net/downloads/
选择busybox-1.32.0.tar.bz2版本
四、根文件系统中目录的介绍
注释:个文件功能解析
bin: 命令文件(通过busybox工具制作)
dev: 设备文件(被操作系统识别的设备才有对应的文件,即设备运行时)
etc: 配置文件(配置内核相关的一些信息)
lib: 库文件、比如C的标准库(从交叉编译工具链中复制的)
linuxrc:根文件系统被挂载后运行的第一个程序(通过busybox工具制作)
mnt: 共享目录(非必要)比如挂载SD卡等时将SD卡挂载在该目录
proc: 与进程相关的文件(当有进程运行时才会有文件)
root: 用户权限(板子本身就是以root用户运行)
sbin: 超级用户命令、一般用户不可用(板子本身是超级用户 通过busybox工具制作)
sys: 系统文件(系统运行时,系统加载后才会有文件)
tmp: 临时文件(比如插入新的设备时会产生临时文件)
usr: 用户文件(通过busybox工具制作)
var: 存放下载的文件和软件 (可有可无)
五、切换交叉编译器为gcc-4.9.4版本(自行寻找合适版本)
六、使用busybox工具制作根文件系统
1、拷贝busybox-1.32.0.tar.bz2到ubuntu中
2、解压缩
tar -vxf busybox-1.32.0.tar.bz2
3、进入到busybox-1.32.0目录
cd busybox-1.32.0
4、make help 获取帮助
Cleaning:
clean
distclean
Build:
all
Configuration:
menuconfig
Installation:
install
uninstall
5、配置编译busybox
1)、修改Makefile配置交叉编译器
164 CROSS_COMPILE ?=
190 ARCH ?= $(SUBARCH)
修改为 :
164 CROSS_COMPILE ?= arm-none-linux-gnueabi-
190 ARCH ?= arm
2)、清除中间文件
make distclean
3)、 执行make menuconfig进行图形化界面配置
make menuconfig
a) 采用静态编译,不使用动态库
Settings —>
[*] Build static binary (no shared libs)
b) 采用vi风格的命令行编辑
Settings —>
[*] vi-style line editing commands
c) 修改根文件系统的安装路径
Settings —>
(./rootfs) Destination path for ‘make install’
d) 支持完整的模块化命令
Linux Module Utilities —>
[ ] Simplified modutils # 去掉*
4)、编译busybox
make all
5)、安装根文件系统
make install
很多的命令都散落在busybox各个目录下,
执行make install 命令将一些根文件系统的命令或者文件
重新定向到指定的根文件系统中。
将新生成的根文件系统拷贝到nfs目录下下
cp rootfs ~/nfs -rf
六、步骤完善根文件系统
1、启动成功,但是有错误信息如下:
can’t run ‘/etc/init.d/rcS’: No such file or directory
can’t open /dev/tty2: No such file or directory
can’t open /dev/tty3: No such file or directory
can’t open /dev/tty4: No such file or directory
解决思路:
<文件不存在就创建文件>
在根文件系统中创建etc/init.d目录,并创建rcS文件
并修改rcS文件的权限为777,
$ cd ~/nfs/rootfs
$ mkdir -p etc/init.d
$ cd etc/init.d
$ touch rcS
$ chmod 777 rcS
打开rcS文件,并添加一下内容:
#!/bin/sh
/bin/mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
解析:
/bin/mount -a:系统会自动解析fstab配置文件,
根据fstab文件中的信息,进行一系列的挂载。
echo /sbin/mdev > /proc/sys/kernel/hotplug:
进行了重定向,告诉内核创建设备文件的程序是
/sbin/mdev
/sbin/mdev -s:在dev目录下创建设备文件
创建dev目录:
$ cd ~/nfs/rootfs
$ mkdir dev
2、在重启开发板出现以下问题
mount: can’t read ‘/etc/fstab’: No such file or directory
解决:
在etc目录下创建fatab文件
$ cd ~/nfs/rootfs
$ cd etc
$ touch fstab
打开fstab,并添加一下内容:
#device mount-point type options dump fsck orde
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
解析:
第一列:设备
第二列:挂载点
第三列:设备类型
其他列:权限相关,默认权限
/etc/init.d/rcS: line 3: can’t create /proc/sys/kernel/hotplug: nonexistent directory
解决办法:
$ cd ~/nfs/rootfs
$ mkdir proc
mdev: /sys/dev: No such file or directory
解决办法:
$ cd ~/nfs/rootfs
$ mkdir sys
3、再次重启开发板,观察现象
mount: mounting tmpfs on /tmp failed: No such file or directory
解决办法:
$ cd ~/nfs/rootfs
$ mkdir tmp
4、再次重启开发板,观察现象
can’t open /dev/tty2: No such file or directory
can’t open /dev/tty3: No such file or directory
can’t open /dev/tty4: No such file or directory
解决办法:
在etc目录下创建inittab文件,
$ cd ~/nfs/rootfs
$ cd etc
$ touch inittab
打开inittab文件,并添加一下内容
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
解析:
::sysinit:/etc/init.d/rcS :
系统启动之后运行linuxrc程序,
执行/etc/init.d/rcS脚本文件
::askfirst:-/bin/sh :
按下任意键之后,开启一个shell的终端
::restart:/sbin/init :
重启系统之后执行/sbin/init
::ctrlaltdel:/sbin/reboot :
按下ctrl + alt + del 执行/sbin/reboot,重启系统
5、再次重启开发板,观察现象。
根文件系统基本制作成功。
将其他的几个文件创建出来:
mkdir lib home mnt root var
6、添加用户名
在etc目录下创建profile文件,并添加一下信息:
export HOSTNAME=linux
export USER=root
export HOME=root
#export PS1="\[\u@\h \W\ ]\$ "
#cd root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
7、编译hello.c的应用程序,使用交叉编译器进行编译,拷贝到开发板中去运行,查看运行结果。
运行之后出现以下出错误:
[root@linux ]# ./hello
-/bin/sh: ./hello: not found
使用以下命令查看hello依赖的动态库是:
arm-none-linux-gnueabi-readelf -d hello
Dynamic section at offset 0xf18 contains 24 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
解决办法: 移植动态库到根文件系统中
从交叉编译器中找对应的动态库。
$ cd ~/toolchain/gcc-4.9.4
$ find . -name libc.so.6
结果
./arm-none-linux-gnueabi/sysroot/lib/libc.so.6
将交叉编译器./arm-none-linux-gnueabi/sysroot/lib/
目录中的所有的动态库,全部拷贝到根文件系统的lib目录下
$ cp -rf ./arm-none-linux-gnueabi/sysroot/lib/* ~/nfs/rootfs/lib
再次在串口工具中执行./hello就成功。
到此根文件系统的移植成功。
七、生成ramdisk.img的镜像文件
1、进入到ubuntu的家目录
$ cd ~
2、执行如下命令制作一个大小为8M的镜像文件
$ dd if=/dev/zero of=ramdisk bs=1k count=8192
3、将该镜像格式化为ext2格式
$ mkfs.ext2 -F ramdisk
4、将该镜像文件挂载到ubuntu下的/mnt目录下
$ sudo mount -t ext2 ramdisk /mnt
5、删除库文件中的符号表减小库文件体积:
$ su root
$ arm-none-linux-gnueabi-strip lib/*
6、将我们自己制作的根文件系统中所有的文件拷贝到该镜像中
$ sudo cp -a /home/linux/nfs/rootfs/* /mnt/
7、解除挂载
$ sudo umount /mnt
8、压缩镜像文件
$ gzip --best -c ramdisk > ramdisk.gz
9、使用mkimage工具为镜像文件添加校验头然后生成可用的镜像ramdisk.img
$ mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
10、将自己制作生成的根文件系统镜像拷贝到tftp的下载目录下并修改其权限
$ cp ramdisk.img /home/linux/tftpboot/
$ chmod 777 /home/linux/tftpboot/ramdisk.img
11、重新配置linux内核使其支持ramdisk文件系统
进入到的linux源码的顶层目录下
$ cd kernel-3.4.39/
执行以下命令进入内核配置界面
$ make menuconfig
在图形化界面中进入到“Device Drivers —>”菜单,再进入“[*] Block devices —>”菜单,将 “RAM block device support” 选为“Y”,将“Default RAM disk size (kbytes)”修改为“8192”,如图所示:
配置完成后保存退出。
回到内核源码的顶层目录下重新编译内核源码:(将交叉编译器切换到4.5.1版本)
$ make uImage
至此,内核可用的根文件系统已经配置好了
更多推荐
所有评论(0)