使用ramdisk和cramfs

使用ramdisk和cramfs

早年写的笔记,压箱底了,翻出来晒晒

目录

使用ramdisk和cramfs1

实验环境... 1

在ramdisk中使用busybox作为init1

配置uClinux内核和busybox. 2

配置启动文件... 3

在uclinux中使用Cramfs5

配置uclinux内核... 5

Cramfs使用Busybox中的init6

制作ramfs7

摸索过程... 7

启动kernel7

Fis可以放在bootscript里面... 8

Inittab的问题... 8

尝试修改G8000. 9

 

 

实验环境

u  IXP425DP(P720 板) 266Mhz 64M ram16M flash

u  FC4: kernel 2.6.11-1.1369_FC4smp(FC6 也行),安装在虚拟机上

u  arm-linux-tools-20051123.tar.gz: gcc 3.4.4编译器

u  snapgear-3.5.0.tar.gz: snapgear 发布的uClinux 包

u  snapgear-modules-20071004.sh: snapgear 发布的uClinux 包

u  Kernel files in /home/linuxuser/snapgear

 

在ramdisk中使用busybox作为init

在前面讲到过,使用默认的配置已经可以启动uclinux2.4了。在此讲解如何在ramdisk中使用busybox作为init,代替系统的init。这对于进一步采用cramfs有帮助。

Busybox的init配置编译完成之后,会在ramdisk根目录下形成linuxrc的链接,并且生成/bin/init,实际上也是个链接。

Kernel command保持为

console=ttyS1,115200root=/dev/ram0 initrd=0x00800000,8Mmem=64M@0x00000000

启动的时候,linuxrc会被先执行。Busybox的initab格式很规矩,并且在/busybox/example下有样例.

 

 

配置uClinux内核和busybox

2.6的配置和2.4的一模一样,因为实际上配置的都是busybox,而不是内核.

在前面讲解一直uClinux2.4的基础上,要加入以下改动。

1.     make menuconfig之后再主菜单中选择Kernel/Library/DefaultsSelection-->Customize Vendor/User Settings。保存退出,会出现Customize Vendor/User Settings的菜单。

 

2.     在Customize Vendor/User Settings的菜单中,选择BusyBox-->init。选中之后,会出现

init: use inittab

init: /linuxrc

init: core dumps

init: support running init from within aninitrd?

除了init: coredumps是debug用的以外一起选上.

 

选完之后保存,使用makedep, make编译。

 

配置启动文件

使用直接的busybox init,这个就需要修改inittab. Rc. Busy box的init和系统提供的不一样。

 

1,修改/etc/inittab

将uclinux生成的ramdisk解压mount之后,假设mount在/tmp文件夹。删除系统原有的/tmp/etc/inittab,可以参考/home/linuxuser/snapgear/user/busybox/examples/inittab。这个文件的内容如下:

 

::sysinit:/etc/init.d/rcS

::askfirst:/bin/sh

::ctrlaltdel:/sbin/reboot

::shutdown:/sbin/swapoff-a

::shutdown:/bin/umount-a -r

::restart:/sbin/init

 

现在ramdisk里实际上没有/etc/init.d/rcS,用/etc/rc代替。同时修改inittab,将

::sysinit:/etc/init.d/rcS

修改为

::sysinit:/etc/rc

那么新的inittab内容如下:

 

::sysinit:/etc/rc

::askfirst:/bin/sh

::ctrlaltdel:/sbin/reboot

::shutdown:/sbin/swapoff-a

::shutdown:/bin/umount-a -r

::restart:/sbin/init

 

2.     修改/etc/rc文件

 

rc原文如下:

hostname IXDP425

mount -t proc proc /proc

mount -o remount,rw /dev/root /

ifconfig lo 127.0.0.1

#insmod ixp400.o

#cat /etc/IxNpeMicrocode.dat > /dev/ixNpe

#insmod ixp400_eth.o

#ifconfig ixp0 192.168.0.1 broadcast 192.168.0.255netmask 255.255.255.0

route add -net 127.0.0.0 netmask 255.255.255.0 lo

#dhcpcd &

cat /etc/motd

必须在文件开始加上#!/bin/sh,否则会报错:Could not run '/etc/rc': Exec format error

 

修改之后rc如下:

#!/bin/sh

hostname IXDP425

mount -t proc proc /proc

mount -o remount,rw /dev/root /

ifconfig lo 127.0.0.1

#insmod ixp400.o

#cat /etc/IxNpeMicrocode.dat > /dev/ixNpe

#insmod ixp400_eth.o

#ifconfig ixp0 192.168.0.1 broadcast 192.168.0.255netmask 255.255.255.0

route add -net 127.0.0.0 netmask 255.255.255.0 lo

#dhcpcd &

cat /etc/motd

 

将umountramdisk之后用gzip压缩,通zImage一起下载到板子上,这样系统就能顺利启动。

 

在uclinux中使用Cramfs

配置uclinux内核

2.6的配置和2.4的一模一样,只不过菜单的位置不同。可以通过打开linux2.4.x或者linux2.6.x下的.config文件搜索来快速确定这些选项在menuconfig中的位置。

 

选中选项

在MemoryTechnology Devices (MTD)选项中进行配置:

Memory Technology Device (MTD) support[Y/m/n/?]Y 内存技术设备支持

MTD partitioning support [Y/m/n/?] Y 支持MTD分区

Direct char device access to MTDdevices[Y/m/n/?] Y MTD字符设备直接访问

Caching block device access to MTDdevices[Y/m/n/?] Y MTD块设备缓冲访问

在File Systems选项中进行配置:

Compressed ROM file system support[Y/m/n/?] Y ROM文件系统的支持

 

修改kernnelcommand line为

console=ttyS1,115200 root=/dev/mtdblock2init=/linuxrc mem=64M@0x0

其中root=/dev/mtdblock2是指制作完成之后的cramfs烧录到flash的第二个分区上。如果是别的分区,需要相应修改。在redboot下查看分区可以使用fis list命令。按照起始地址的大小顺序数,mtdblock从0开始计数,通常redboot分区是mtdblock0。在当前的IXDP425板上,准备烧录的分区的起始位置第三大,所以应该是mtdblock2 。

 

完成上述修改并编译后,完成uCliunx内核对CramFS文件系统的支持。

 

 

Cramfs使用Busybox中的init

在实际的使用中cramfs也是经常采用的一种文件格式。相对特殊的地方是cramfs是只读的。而init的过程中使用的几个重要文件/etc/inittab, /etc/rc等必须在调用busybox linuxrc之前存在。如果存在,那么Cramfs的操作和ramdisk是一样。但是如果不是,则必须先利用里一个脚本准备。

假设有一个系统,因为只读文件的原因。etc只是一个链接到/var/etc,真正的内容是启动的时候复制/usr/etc到/var/etc,那么这个操作必须提前。

删除busybox生成的linuxrc,建立脚本如下。

 

#!/bin/sh

#

PATH=/bin:/sbin:/usr/bin:/usr/sbin

export PATH

/bin/mount -n none /proc -t proc

/bin/mount -n tmpfs /var -t tmpfs-o size=18000000

/bin/mkdir -p /var/run /var/tmp/var/etc /var/log

/bin/mkdir -p /var/empty   ##for sshd

cd /dev && /bin/tar cf /tmp/dev.tar .;cd /

/bin/mount -n tmpfs /dev -t tmpfs -osize=100000

cd /dev && /bin/tar xf /tmp/dev.tar&& rm -f /tmp/dev.tar; cd /

cp /usr/etc /var -rf

bin/busybox linuxrc

 

其中前面的步骤是挂载文件系统,准备好文件,其中准备etc的为下面几句

/bin/mount -n tmpfs /var -t tmpfs-o size=18000000

/bin/mkdir -p /var/run /var/tmp/var/etc /var/log

cp /usr/etc /var –rf

先挂载/var, 建立/var/etc,然后复制/usr/etc。这样,在根目录下的etc就能包含内容了。最后一句实际上就代替了busybox原来的linuxrc。如果想查看busybox的这种用法,可以在系统启动之后,输入busybox就可以。

# busybox

BusyBox v1.00(2009.04.15-07:30+0000) multi-call binary

 

Usage: busybox [function][arguments]...

   or: [function] [arguments]...

 

        BusyBox is a multi-call binary thatcombines many common Unix

        utilities into a singleexecutable.  Most people will create a

        link to busybox for each function theywish to use, and BusyBox

        will act like whatever it was invokedas.

 

Currently definedfunctions:

        [, adjtimex, ar, basename, busybox,cat, chgrp, chmod, chown,

        chroot, clear, cmp, cp, cut, date, dc,dd, df, dirname, dmesg,

        du, echo, env, expr, false, find, free,freeramdisk, getopt, grep,

        gunzip, gzip, halt, head, hostname, id,init, insmod, kill, killall,

        klogd, length, linuxrc, ln, logger,logname, ls, lsmod, makedevs,

        md5sum, mkdir, mknod, mktemp, modprobe,more, mount, mv, nc, nslookup,

        pidof, printf, ps, pwd, rdate,readlink, reboot, renice, reset,

        rm, rmdir, rmmod, sed, sleep, sort, stty,sync, syslogd, tail,

        tar, tee, telnet, test, tftp, touch,tr, true, tty, umount, uname,

        uniq, uptime, usleep, vi, wget, which,whoami, xargs, yes, zcat

 

制作ramfs

将根文件系统准备好之后,下载cramfs-1.1.tar.gz,在PC下编译。生成两个文件cramfsck和mkcramfs。

假设根文件系统的文件夹为cramroot.用以下命令制作cramfs映像。

Mkcramfs ./cramroot cram.img

得到cram.img,将其烧到板子上就行了。

 

摸索过程

启动kernel

按照文中的方法编译好内核之后,每次启动到kernel就没有任何信息。

 

RedBoot> exec

Using base address 0x01600000 and length 0x00100000

就没有反应了.

说明kernel根本没有起来。

使用console=ttyS1,115200root=/dev/ram0 initrd=0x00800000,8Mmem=64M@0x00000000就完全没有问题。

所以肯定是kernelcommand line出了问题。后来经过提示,发现

Console =ttyS1,115200 root=/dev/mtdblock2init=/linuxrc mem=64M@0x0

发现是console和等号之间的空格问题导致command line不能解析。

 

修改完可以打印许多kernel启动的信息,但是出现错误如下:

NET: Registered protocol family 17

Time: OSTS clocksource has been installed.

VFS: Mounted root (cramfs filesystem)readonly.

Freeing init memory: 108K

Warning: unable to open an initial console.

说明已经kernel正常启动, initial出了点问题.

 

一个问题: /dev/没有console这个文件。
#mknod -m 600 /dev/console c 5 1
#mknod -m 666 /dev/null c 1 3

检查dev的问题,发现G8000flashdisk文件夹下面有两个文件可以生成/dev下的节点,这就完全解释了dev的现象。

 

Fis可以放在boot script里面

 

因为测试cramfs,需要每次都重新烧flash。

Fis 可以放在boot script里面,并且没有覆盖提示

Enter script, terminate with empty line

>> load -r -v -b 0x0080000026cram.img

>> fis create -b 0x00800000 -l0x240000 -f 0x50180000 -e 0x00800000 -r 0x00800000 ramdisk

>> load -r -v -b 0x01600000 zImage

>> exec

>> 

这样可以方便的调试cramfs.

 

Inittab的问题

经过以上的调试之后,可以看到kernel已经成功的执行linuxrc下的指令,但是始终不出现登录提示符。因为登录提示符在Inittab。如果在linuxrc里面加上/bin/sh,是可以出现提示符的,但是Inittab里面的syslogd等都不执行了。仔细检查Inittab,发现和网上讲解的格式不一样。这个是系统自带的Inittab,而不是busybox样本的。原文如下:

inet:unknown:/bin/inetd

boa:unknown:/bin/boa

slog:unknown:/sbin/syslogd -n

klog:unknown:/sbin/klogd -n

 

并没有4个部分如id,runlevel等。多次尝试使用uclinux自带的init始终无法成功。于是决定全部采用busybox的init方法。

 

查看busybox的Inittab样本说明如下:

# Format for each entry:<id>:<runlevels>:<action>:<process>

#

# <id>: WARNING: This field has anon-traditional meaning for BusyBox init!

#

#   The id fieldis used by BusyBox init to specify the controlling tty for

#   thespecified process to run on.  Thecontents of this field are

#   appended to"/dev/" and used as-is.  Thereis no need for this field to

#   be unique,although if it isn't you may have strange results.  If this

#   field isleft blank, it is completely ignored. Also note that if

#   BusyBoxdetects that a serial console is in use, then all entries

#   containingnon-empty id fields will _not_ be run. BusyBox init does

#   nothing withutmp.  We don't need no stinkin' utmp.

#

# <runlevels>: The runlevels field iscompletely ignored.

#

# <action>: Valid actions include: sysinit,respawn, askfirst, wait, once,

#                                  restart,ctrlaltdel, and shutdown.

#

#       Note:askfirst acts just like respawn, but before running the specified

#       processit displays the line "Please press Enter to activate this

#      console." and then waits for the user to press enter beforestarting

#       thespecified process.

#

#       Note:unrecognised actions (like initdefault) will cause init to emit

#       anerror message, and then go along with its business.

#

# <process>: Specifies the process to beexecuted and it's command line.

 

 

尝试修改G8000

想让G8000使用ramdisk,修改完command line为如下

console=ttyS1,115200 root=/dev/ram0 init=/linuxrcmem=64M@0x0

启动发现如下错误

Bridge firewalling registered

802.1Q VLAN Support v1.8 Ben Greear<[email protected]>

Other stuff added by David S. Miller<[email protected]>

NetWinder Floating Point Emulator V0.97 (doubleprecision)

VFS: Cannot open root device "ram0" or01:00

Please append a correct "root=" boot option

Kernel panic: VFS: Unable to mount root fs on 01:00

 

还是启动失败。应该和kernel的支持有关。

configure kernel with

- ramdisk support

- ramdisk support as boot device

- extended fs 2 support

 

重新编译内核之后还是不行,但是错误信息已经变了。

 

cramfs: wrongmagic

Kernel panic:VFS: Unable to mount root fs on 01:00

 

也许是0x00800000的启动位置问题。

 

修改commandline为console=ttyS1,115200root=/dev/ram0 init=/linuxrc initrd=0x00800000 mem=64M@0x0 reboot=h

 

还是出现问题。

RAMDISK: Compressed image found at block 0

Freeing initrd memory: 8192K

VFS: Mounted root (ext2 filesystem) readonly.

Freeing init memory: 64K

attempt to access beyond end of device

01:00: rw=0, want=8297, limit=8291

EXT2-fs error (device ramdisk(1,0)): ext2_read_inode:unable to read inode block - inode=1602, block=8296

Warning: unable to open an initial console.

attempt to access beyond end of device

01:00: rw=0, want=8348, limit=8291

EXT2-fs error (device ramdisk(1,0)): ext2_read_inode:unable to read inode block - inode=2016, block=8347

attempt to access beyond end of device

01:00: rw=0, want=16388, limit=8291

EXT2-fs error (device ramdisk(1,0)): ext2_read_inode:unable to read inode block - inode=3201, block=16387

Kernel panic: No init found.  Try passing init= option to kernel

 

这个似乎是说ramdisk超过的限度。

 

修改ramdisk size= 26624以及

console=ttyS1,115200 root=/dev/ram0initrd=0x00800000,26Mmem=64M@0x00000000

EXT2-fs error错误消失。说明确实是这个问题。

 

修改完之后还是有错误

VFS: Mounted root (ext2 filesystem) readonly.

Freeing init memory: 64K

Warning: unable to open an initial console.

Kernel panic: No init found.  Try passing init= option to kernel.

那应该是init的位置不对。

网上找到的信息。

很显然是你的init不对,现在你的文件系统是被挂载上去了,因为zkernelsource里面的init/main.c 里面的init函数调用了/sbin/init或者是/etc/init ,详细你可以看一下init/main.c,另外你要挂载ramdisk /dev/下只需要ramram0什么的就可以了。

 

 

不过到此为止,说明kernnel已经完全可以用了。剩下的的就是init之类的事情。

你可能感兴趣的:(使用ramdisk和cramfs)