制作Ramdisk文件系统
主机:ubuntu14.04
工具链:arm-none-linux-gnueabi-4.8.3
linux: linux-3.14.67
一:配置内核:
#make menuconfig ARCH=arm
打开配置菜单,修改两个配置项,分别是:
a):General setup-->选择 Initial RAM filesystem and RAM disk...... 项
b):Device Drivers-->Block devices-->选择 RAM block device support 项
c) :选上Default RAM disk size kbytes选项为(4096)Default RAM disk size kbytes,因为制作的ramdisk是4096KB大小的。如果这个大小和你做的ramdisk不匹配,则启动时仍然会出现kernel panic内核恐慌,提示ramdisk格式不正确,挂载不上ramdisk。然后特别要注意的一点是,ramdisk是一种内存虚拟磁盘技术,实质上并不是一种文件系统,它使用的文件系统时ext2文件系统。所以一定要在make menuconfig ARCH=arm的时候进入File systems菜单,选上<*> Second extended fs support。以提供内核对ext2文件系统的支持。我以前添加过了ext2文件系统了,然后保存配置退出。这样就为内核添加好了ramdisk启动功能和ramdisk的驱动支持了。
d)修改内核启动参数
方法有二:
1):修改.config,修改CONFIG_CMDLINE=""的定义
修改为CONFIG_CMDLINE="initrd=0x53000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64M" (0x53000000,0x200000-ramdisk镜像在内存的加载地址。0x200000:大小)
保存。
意思为从ramdisk启动,ramdisk压缩文件起始地址在内存地址0x53000000处,文件大小为0x200000。
此参数也可以在make menuconfig ARCH=arm时进入Boot options菜单,然后在Default kernel command string里修改。效果是一样的。
2):或者不修改.config,而是用u-boot的bootargs环境变量来传递启动参数。
同样也是修改该环境变量为bootargs=initrd=0x53000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64M
并saveenv保存u-boot环境变量
以上1),2)的效果是一样的。
e)编译内核
#make uImage ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
二:根文件系统的制作:
a):建立目录
#sudo mkdir ramdiskfs
#cd ramdiskfs
#sudo mkdir mnt tmp var usr sys proc etc lib dev bin sbin root home
#sudo mkdir usr/bin usr/sbin usr/lib lib/modules
目录创建完成
b):添加设备文件
#sudo cd dev
#sudo mknod -m 666 console c 5 1 (备注:创建控制台设备文件)
#sudo mknod -m 666 null 1 3 (备注:创建一个空的设备文件)
c):添加配置文件
(1):第一种方法:可以复制busybox中的/examples/bootfloppy/etc的文件
(2):参考以前已经有的文件系统的配置文件复制到创建的ramdiskfs的 /etc目录
d):编译busybox
(1)下载busybox,网站https://busybox.net/downloads/ 下载想要的目录 也可以使用 wget https://busybox.net/downloads/busybox-1.24.1.tar.bz2 (备注:wget命令下载源文件到当前目录,-p可以指定目录,详情百度或者wget --help)
(2)解压busybox,
(3)配置busybox
进入busybox目录执行#make menuconfig
进入Busybox Settings -> build Options ->选中"Build busybox as a static binary“,即静态链接,免去拷贝大量的库文件。
指定cross compile prefix :(一般是:arm-linux-)我这里是指定特定的编译工具链/arm-linux/arm-none-linux-gnueabi-4.8.3/bin/arm-none-linux-gnueabi-
(备注:这里必须指定,否则编译出来的busybox会少0.1M,在bootloader加载ramdisk.gz时会报没有可用的块,报kernel panic)
Busybox Installation Prefix (/xxx/ramdiskfs),修改该选项表明编译后的busybox将安装到该位置。
(4)编译、安装busybox
#make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- (上面指定了这里可以不需要)
几分钟编译完成后
#make install
安装到Busybox Installation Prefix (/xxx/ramdiskfs)设定的目录里。当前为我要制作的根文件系统目录(/xxx/ramdiskfs)。
e)制作ramdisk根文件系统镜像
(1)第一种方法:(建议采用这种方便)
上http://genext2fs.sourceforge.net/下载可以简单方便的制作ramdisk文件系统的工具genext2fs,这样就不用像网上大多数说的那样繁琐的制作ramdisk映像了,当前最新版本为genext2fs-1.4.1.tar.gz ,下载具体地址:http://sourceforge.net/projects/genext2fs/?source=dlp
解压,配置(./configure),编译(make),在当前目录下生成该工具genext2fs,并将其放入宿主机的/sbin/目录下以方便使用。
跳转到要制作的ramdiskfs的上一级目录
#genext2fs -b 4096 -d ramdsikfs ramdisk
-b是指制作的ramdisk大小为4096K字节
-d是指要制作成ramdisk的根文件系统目录
最后的ramdisk是制作出来的ramdisk的名字,当然可以改名了。
#gzip -v9 -f ramdisk
将该ramdisk以最优方式压缩为ramdisk.gz
(2)第二种方法:
自己建立根文件系统(应用mk2fs工具)
1.建立loop设备的临时挂载点
#mkdir /mnt/loop
2.建立文件系统映象
#dd if=/dev/zero of=/tmp/ramdisk bs=1k count=4096
创建一个大小4096k的文件,初始化为0
3.mke2fs –F –v –m 0/tmp/ramdisk
此处-F选项将可迫使mke2fs在文件上运行。否则mke2fs会抱怨/tmp/ramdisk不是个块设备(/tmp/ramdisk文件映象必须是块设备文件)。-v选项指出mke2fs应该以verbose模式执行,-m0指出不必在文件系统上为“超级用户”保留任何区块,因为在嵌入式系统中通常是单用户系统,为“超级用户”保留区块没有意义。
4.挂载映象文件
#munt –o loop /tmp/ramdisk /mnt/loop
挂载后,在/mnt/loop下就可以对文件系统的内容进行操作。-loop 是以一个文件以块的方式挂载
5.cp操作
将需要的文件等复制到目录下。
6.卸载映象文件
#umount /mnt/loop
7.压缩映象文件
#gzip –v9 /tmp/ramdisk
这样就可以测试ramdisk.gz了。
(3)第三种方法
1、建立loop设备的临时挂载点
#mkdir /mnt/loop
2、建立一个大小为4096k的临时文件
#dd if=/dev/zero of=/tmp/loop bs=1k count=4096
注意可根据自己的需要建立大小合适的文件系统,更改count大小即可。
此处以dd命令建立一个了一个40996KB文件系统映象,存于/tmp/loop,并以.dev/zero对它进行初始化。用这种方式对文件系统进行初始化,稍后当我们使用gzip命令压缩整个映象时,将让文件系统中未使用的部分获得最大压缩比。
3、将设备文件与临时文件联系起来
#losetup /dev/loop0 /tmp/loop
把设备文件/dev/loop0与临时镜象文件/tmp/loop系起来,/dev/loop0是个块设备
如果出现“ioctl:LOOP_SET_FD:设备或资源忙”,说明/dev/loop0设备还和一文件联系,可用losetup /dev/loop0查看地,并可用-d 删除。
如:losetup -d /dev/loop0 即可删除。
4、将/dev/loop0格式化为ext2文件系统
#mke2fs –m 0 /dev/loop0
-m 0指出不必在文件系统上为“超级用户”保留任何区块。
Linux内核识别两种可以直接考贝的到ramdisk的文件系统,它们是minix和ext2,minix是linux早期版本所用的文件系统,从minix操作系统而来,ext2性能更好。
5、把虚拟盘挂在节点/mnt/loop上
#mount –t ext2 /dev/loop0 /mnt/loop
6、用cp –af命令将所需要文件拷贝到虚拟盘上
cp –help查看cp 用法。cp –arf … -r表示拷贝目录
/bin, /dev, /etc, /lib, proc, /sbin, /usr都是不可或缺的目录,建议保留/tmp,/var,不过可以为空。而为多用户提供可扩展环境的所有目录(例如/home、/mnt、/opt、/root)都应该省略。
用cp复制文件时,建议把已建立好的文件系统中的内容全部拷贝过来,这样比较简单,不需要再去编译安装busybox等。当然自己也可以那样去做。
7、卸载文件系统,得到的/tmp/loop就是文件系统映象。
#cd /mnt/loop以外的目录 (否则会提示无法卸载,设备busy)
#umount /mnt/loop
8、压缩文件系统映象
#gzip –v9 /tmp/loop ramdisk
在/tmp下生成了ramdisk.gz,这样一个内存文件镜象生成了。
在一个已建好的文件系统上进行修改
设已建立好的文件系统压缩文件为ramdisk.gz
1、解压
#cd ramdisk.gz所在目录
#gunzip ramdisk.gz
在解压后,得到文件系统镜象文件ramdisk, 覆盖了原来的压缩文件
2、镜象文件挂载
镜象文件必须经过挂载后才能看到文件系统中的各个目录和详细内容
#mkdir /mnt/loop
/mnt/loop 是文件系统要挂载到的目录
#mount –o loop ramdisk /mnt/loop
3、在挂载目录/mnt/loop下对文件系统进行操作
#cd /mnt/loop
根据需要增加、删减或是修改文件系统的内容
4、卸装文件系统
跳到/mnt/loop目录外,否则无法卸装,提示busy
#cd ramdisk所在目录
#umount /mnt/loop
5、压缩文件系统
#gzip –v9 ramdisk /*生成ramdisk.gz压缩文件
这样就可以测试ramdisk.gz
测试ramdisk.gz
a)在uboot的bootargs 配置内核时需要的参数,initrd=0x53000000,0x200000 root=/dev/ram,rw init=/linuxrc console=ttySAC0,115200 mem=64M
b)tftp 0x52000000 uImage tftp 0x53000000 ramdiskfs.gz tftp 0x54000000 s3c6410OFsbc.dtb
bootm 0x52000000 0x53000000 0x54000000
c)如果出现:
Wrong Ramdisk Image Format Ramdisk image is corrupt or invalid
解决方式
mkimage -n 'uboot ext2 ramdisk rootfs' -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdiskfs.gz
说明:mkimage工具是u-boot格式镜像制作工具。如果成功编译u-boot之后,它会在u-boot源码树下的tools目录之下。建议将其拷贝到宿主机的/sbin/目录下,以方便使用。mkimage使用时的具体参数不再详述,不清楚的请自己查阅
-A ==> set architecture to 'arch' //用于指定CPU类型,比如ARM
-O ==> set operating system to 'os' //用于指定操作系统,比如Linux
-T ==> set image type to 'type' //用于指定image类型,比如Kernel
-C ==> set compression type 'comp' //指定压缩类型
-a ==> set load address to 'addr' (hex) //指定image的载入地址
-e ==> set entry point to 'ep' (hex) //内核的入口地址,一般是:image的载入地址+0x40(信息头的大小)
-n ==> set image name to 'name' //image在头结构中的命名
-d ==> use image data from 'datafile' //无头信息的image文件名
-x ==> set XIP (execute in place) //设置执行位置
移植e2fsprogs--可以增加mkfs.ext4等命令的支持
a)下载https://sourceforge.net/projects/e2fsprogs/files/e2fsprogs/
b)解压
c)配置:
由于e2fsprogs通常会用到动态库,这里为了方便起见,采用了静态链接。
这样的话,向arm平台拷贝时,就不需要再关心动态库的问题了。
具体操作过程如下:
tar -xzf e2fsprogs-1.42.5.tar.gz
cd e2fsprogs-1.42.5
mkdir release
cd release/
../configure --host=arm-linux CC=arm-linux-gcc LDFLAGS=-static
make
好了,现在release下面的各个目录下,已经有相应的可执行程序生成了。
将他们直接拷到arm平台下即可使用了。
当然,如果单板flash空间紧张的话,则可以将部分功能编译成动态库。
方法如下:
../configure --host=arm-linux CC=arm-linux-gcc --enable-elf-shlibs
make
好了,release下面的相应子目录中已经生成了可执行文件及动态库。
接下来要拷贝文件了。
假如我们需要release/misc/mke2fs这个程序。
那么首先用readelf看看mke2fs需要使用哪些动态库。
[[email protected] relaese]# readelf -d misc/mke2fs
Dynamic section at offset 0x11474 contains 30 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libext2fs.so.2]
0x00000001 (NEEDED) Shared library: [libcom_err.so.2]
0x00000001 (NEEDED) Shared library: [libblkid.so.1]
0x00000001 (NEEDED) Shared library: [libuuid.so.1]
0x00000001 (NEEDED) Shared library: [libe2p.so.2]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.0]
可以看出一共需要7个库。由于最后两个是标准C库,板子上本来就有。
因此,我们只需要拷贝前5个即可。
好了,我们先将release/lib目录下对应的5个动态库拷贝到单板的/lib目录下,
然后将release/misc/mke2fs拷贝到单板的/sbin目录下即可。
------------------------------------------------------------------------------------------------------------------------------
借鉴:
1,http://blog.****.net/yimiyangguang1314/article/details/8493089
2,http://blog.sina.com.cn/s/blog_4a70d5d901012l57.html
3,http://blog.****.net/linuxarmsummary/article/details/12612269
4,http://blog.****.net/crazycoder8848/article/details/8510775
5,http://www.360doc.com/content/11/0223/15/3038654_95421411.shtml