使用BusyBox制作linux根文件系统(CramFS+mdev)

[Linux驱动开发] cramfs文件系统制作及移植 制作cramfs文件系统 此处将上一篇博文制作的first_fs文件系统拷贝到/opt中,并更改名称为rootfs 我们要做的是将rootfs文件系统制作成cramfs类型的文件系统,并将其烧录到Nand Flash中 1、准备事项: 添加内核菜单选项: make menuconfig General setup  --->     (设置通用设置) [*] Configure st 阅读详情
操作系统:Ubuntu9.04
内核版本:linux-2.6.24.7  
开发板:博创arm2410s    
交叉编译工具:arm-linux-gcc-4.1.1 
BusyBox:busybox-1.11.1      
CramFS:CramFS-1.1
 
注意:由于要制作的根文件系统使用了mdev(BusyBox简化版的udev),因此,需要内核支持sysfs、procfs和ramfs(tmpfs)文件系统以及hotplug(uevent)事件机制。
 
浅蓝色为命令, 橘红色为代码和脚步
1、准备根文件系统
使用shell脚本create_rootfs.sh,建立根文件系统的目录框架
lingd@ubuntu:~/arm2410s$ vi create_rootfs.sh

create_rootfs.sh内容如下:
#!/bin/sh
echo "------Create rootfs directons......"
mkdir rootfs
cd rootfs
echo "--------Create root,dev......"
mkdir root dev etc bin sbin mnt sys proc lib home tmp var usr
mkdir usr/sbin usr/bin usr/lib usr/modules
mkdir mnt/usb mnt/nfs mnt/etc mnt/etc/init.d
mkdir lib/modules
chmod 1777 tmp
cd ..
echo "-------make direction done---------"


为create_rootfs.sh添加执行权限
lingd@ubuntu:~/arm2410s$ chmod a+x create_rootfs.sh
执行create_rootfs.sh,建立根文件系统的目录框架
lingd@ubuntu:~/arm2410s$ ./create_rootfs.sh
lingd@ubuntu:~/arm2410s$ cd rootfs
lingd@ubuntu:~/arm2410s/rootfs$ ls
bin  dev  etc  home  lib  mnt  proc  root  sbin  sys  tmp  usr  var



2、创建设备文件
mdev 是通过 init 进程来启动的,在使用 mdev 构造 /dev 目录之前,init 至少要用到设备文件 /dev/console、  /dev/null,所以需要事先建立这两个设备文件:
lingd@ubuntu:~/arm2410s/rootfs$ cd dev
lingd@ubuntu:~/arm2410s/rootfs/dev$ sudo mknod -m 660 console c 204 64
[sudo] password for lingd: 
lingd@ubuntu:~/arm2410s/rootfs/dev$ sudo mknod -m 660 null c 1 3
lingd@ubuntu:~/arm2410s/rootfs/dev$ ls -l
total 0
crw-rw---- 1 root root 5, 1 2010-04-02 15:49 console
crw-rw---- 1 root root 1, 3 2010-04-02 15:50 null


注意:本来console的主次设备号应为5和1.但是因为init在执行完/etc/init.d/rcS脚本后,就会在一个控制台上,按照inittab的指示开一个shell(或者是开getty+login,这样用户就会看到提示输入用户名的提示符)。在mdev -s未执行之前,/dev目录下只有我们创建的/dev/null和/dev/console,也就是说,没有控制台可供init用来按照inittab的指示开一个shell。而在s3c24xx 系列芯片的串口驱动里面用了s3c2410_serial做为设备名(在内核源码的“drivers/serial/s3c2410.c”文件的949行),因此,启动时可用s3c2410_serial0、s3c2410_serial1或s3c2410_serial2作为init用来按照inittab的指示开一个shell的控制台,这里我用了串口0,即s3c2410_serial0(主次设备号为204和64)作为控制台。这里直接将console当s3c2410_serial0,所以console的主次设备号才会为204和64。

3、准备一些配置文件和系统启动时所需的文件
3.1、mdev配置文件 mdev.conf
mdev会在/etc目录下找mdev的配置文件:  mdev.conf. 如果该文件不存在,那么在执行mdev –s这个命令时,会提示找不到mdev.conf。我们不需要mdev规则,所以只是touch生成一个空文件就OK了。当然也可以根据mdev的规则来编写mdev.conf。我把所有配置文件都是在/mnt/etc下,而不是/etc,后面解释这么做的原因。
lingd@ubuntu:~/arm2410s/rootfs/dev$ cd ../mnt/etc
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ touch mdev.conf
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d  mdev.conf


3.2、 linuxrc
linuxrc位于根文件系统的顶层目录/,这里为rootfs。/Linuxrc 执行init 进程初始化文件。主要工作是把已安装根文件系统中的/etc 安装为ramfs,并拷贝/mnt/etc/目录下所有文件到/etc,这里存放系统启动后的许多特殊文件;接着Linuxrc 重新构建文件分配表inittab;之后执行系统初始化进程/sbin/init。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ cd ../..
lingd@ubuntu:~/arm2410s/rootfs$ vi linuxrc

linuxrc内容如下:
#!/bin/sh
echo "Processing /linuxrc"

echo "mount /etc as ramfs"
/bin/mount -n -t ramfs ramfs /etc       
/bin/cp -a /mnt/etc/* /etc

echo "re-create the /etc/mtab entries"
/bin/mount -f -t cramfs -o remount,ro /dev/bon/3 /
/bin/mount -f -t ramfs ramfs /etc

echo "start init"
exec /sbin/init



lingd@ubuntu:~/arm2410s/rootfs$ ls
bin  dev  etc  home  lib  linuxrc  mnt  proc  root  sbin  sys  tmp  usr  var

Linuxrc脚本分析
/bin/mount -n -t ramfs ramfs /etc 
这句话的作用加载一个ramfs作为/etc目录。这样/etc就是一个可写目录。
从这个脚本可知,你的根文件系统是一个cramfs(只读文件系统),而/etc作为系统运行配置文件的存放地点,可能会写一些运行状态在这里,linuxrc第一件事情就是将一个ramfs mount到/etc只读目录中,使得/etc/目录可写,指定参数 -n的目的是告诉mount不要写/etc/mtab, 这个文件存放当前系统已挂载(mount)的文件系统清单。因为现在/etc/目录还是只读,所以这次mount不要写这个文件,否则会失败。而且mount上后,原/etc会覆盖掉(原/etc下的文件都不见了,umount后会重新出现),所以我们把配置文件都保存在/mnt/etc,mount上ramfs到/etc后,再把配置文件拷贝到/etc。而不是直接将配置文件保存在/etc/下

 /bin/cp -a /mnt/etc/* /etc
/etc成为可写目录后,将所有/mnt/etc中的配置文件拷贝到/etc/中,这说明ramfs可能是一个空的ramfs,没有配置文件,或者配置文件比较老。同时也说明这个系统是一个只读系统,每次系统运行中写入的配置不会保留。
将以前mount的那些信息重新写到/etc/mtab中,命令就是下面这些。
/bin/mount -f -t cramfs -o remount,ro /dev/bon/3 /
/bin/mount -f -t ramfs ramfs /etc
这些命令只是将这些mount信息写到/etc/mtab中,不会实际去mount这些block device,说明你的根文件系统依然是以前的那个/dev/bon/3
exec /sbin/init
执行根文件系统中的init执行程序,使其成为1号进程。shell正式运行。

3.3、 rcS
rcS文件位于/etc/init.d,是busybox版init第一个运行的脚步(常见的init还有Sys V init版,其第一个执行的脚步是/etc/rc.d/rc.sysinit)。/mnt/etc/init.d/rcS 完成各个文件系统的 mount,再执行/mnt/etc/rc.local;通过rcS 可以调用 ifconfig 程序配置网络。rcS 执行完了以后,init 就会在一个 console 上,按照 inittab 的指示开一个 shell,或者是开 getty + login,这样用户就会看到提示输入用户名的提示符。/etc/init.d/rcS文件内容如下:
lingd@ubuntu:~/arm2410s/rootfs$ cd mnt/etc/init.d
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc/init.d$ vi rcS

/etc/init.d/rcS内容如下:
#!/bin/sh
echo "Processing /etc/init.d/rcS"

echo "mount -a"
mount -a #mount上fstab文件中所有文件系统
exec /etc/rc.local



3.4、 /etc/rc.local 
/etc/rc.local是被init.d/rcS 文件调用执行的特殊文件,与Linux 系统硬件平台相关,如安装核心模块、进行网络配置、运行应用程序、启动图形界面等。内容如下:
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc/init.d$ cd ..
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi rc.local

/etc/rc.local内容如下:
#!/bin/sh
echo "Processing /etc/rc.local"

echo "get hostname"
/bin/hostname -F /etc/hostname

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

echo "ifconfig eth0 192.168.1.21"
ifconfig eth0 192.168.1.21

echo "**************************************************"
echo "*                                                *"
echo "*        lingd  rootfs for linux 2.6.24.7        *"
echo "*                                                *"
echo "*          arm-linux-gcc version 4.1.1           *"
echo "*                                                *"
echo "*                 2010-03-30                     *"
echo "*                                                *"
echo "**************************************************"



lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d  rc.local

在rc.local使用了"/bin/hostname -F /etc/hostname"来设置主机名(设置主机名主要是为了后面设置命令提示符PS1)。这条命令需要了一个主机名配置文件/etc/hostname,其内容如下:
arm2410s

3.5、 /etc/profile
rc.local 首先执行该文件配置应用程序需要的环境变量等。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi profile
/etc/profile内容如下:
#/etc/profile
echo "Processing /etc/profile"
echo "set user path"
PATH=/bin:/sbin:/usr/bin:/usr/sbin 

echo "set search library path"
LD_LIBRARY_PATH=/lib:/usr/lib

echo "set PS1"
HOSTNAME=`/bin/hostname`
PS1='\u@\h:\w\$ ' #设置命令提示符为ubuntu风格
export PATH LD_LIBRARY_PATH HOSTNAME PS1



lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d  profile  rc.local


改变这四个文件的权限
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ cd ../..
lingd@ubuntu:~/arm2410s/rootfs$ chmod 775 linuxrc mnt/etc/init.d/rcS mnt/etc/rc.local mnt/etc/profile


3.6、 /etc/inittab
内核引导完成后,内核会启动初始化进程init(用户级进程)来进行系统的各项配置。init是系统第一个进程,它是系统上运行的所有其他进程的父进程,他会观察其子进程,并在需要时启动、停止、重启它们。init主要是用来完成系统的各项配置。init从/etc/inittab获取所有信息。想了解BusyBox init及其inittab基本原理的,可以看这篇文章 http://blog.chinaunix.net/u3/109117/showart_2208026.html。 lingd@ubuntu:~/arm2410s/rootfs$ cd mnt/etc
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi inittab

/etc/inittab内容如下:
#/etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh    
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r


"console::askfirst:-/bin/sh"中的-表示的是让busybox开启一个登录(login)shell,login shell在执行前都会读取配置文件/etc/profile和.profile。由BusyBox源码的shell/ash.c文件可知这一点:
int ash_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
    …………
    if (argv[0] && argv[0][0] == '-')
        isloginsh = 1;
    if (isloginsh) {
        state = 1;
        read_profile("/etc/profile");
state1:
        state = 2;
        read_profile(".profile");
    …………
}

因为我们在/etc/profile对PATH、LD_LIBRARY_PATH、HOSTNAME、PS1等环境变量进行了修改,所以BusyBox开启的必须是一个login shell(这样可以保证/profile的内容对开发板上所有shell都是有效的);否则/etc/profile定义的内容将不会执行。
做个小实验(以这次做好的根文件系统为基础):
Please press Enter to activate this console.         #启动开发板,引导linux内核并进行各系统配置后,执行到这里。按下回车键,显示以下内容:                             
starting pid 797, tty '/dev/console': '-/bin/sh '    #在控制台/dev/console上开启一个login shell                             
Processing /etc/profile                              #执行/etc/profile配置文件                             
set user path                                                                     
set search library path                                                           
set PS1       
root@arm2410s:/#                                                        
root@arm2410s:/# exit     #退出当前shell                                                        
                                                                                  
Please press Enter to activate this console.          #再按回车开启一个新的login shell                            
starting pid 799, tty '/dev/console': '-/bin/sh '                                 
Processing /etc/profile                               #再次执行/etc/profile配置文件                           
set user path                                                                     
set search library path                                                           
set PS1
 

lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d  inittab  profile  rc.local


3.7、 /etc/fstab
文件/etc/fstab存放的是系统中的文件系统信息。当正确的设置了该文件,则可以通过"mount /directoryname"命令来加载一个文件系统,或mount -a来加载该文件中所有文件系统。每种文件系统都对应一个独立的行,每行中的字段都有空格或tab键分开。同时fsck、mount、umount的等命令都利用该程序。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi fstab
fstab文件内容如下:
#/etc/fstab: static file system information.
#<File system> <mount pt>     <type>   <options>         <dump> <pass>
proc  /proc proc  defaults 0 0
sysfs /sys  sysfs defaults 0 0
mdev  /dev  ramfs defaults 0 0
none  /tmp  ramfs defaults 0 0

注意:已单独mount了的文件系统,就不要出现在/etc/fstab文件中,以免使用mount -a时把先前已经mount上的文件系统被覆盖了。
 
3.8、/etc/passwd
/etc/passwd文件存放着所有用户的信息,包括账号和密码。内容如下:
#username:password:User ID:Group ID:comment:home directory:shell
root:x:0:0:root:/root:/bin/sh
 

4、编译busybox
BusyBox下载地址: http://www.busybox.net/
lingd@ubuntu:~/arm2410s$ tar xjvf busy-1.11.1.tar.bz2
lingd@ubuntu:~/arm2410s$ cd busybox-1.11.1
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ vi Makefile

首先修改 Makefile ,将以下两项改为
CROSS_COMPILE = arm-linux-
ARCH      = arm


配置busybox,修改以下选项(其他选项默认就可以了,或者根据需要再裁减一下):
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ make menuconfig
Busybox Settings  ---> 
Build Options  --->
     [*] Build BusyBox as a static binary (no shared libs)
     [ ] Build with Large File Support (for accessing files > 2 GB)
Installation Options  --->
     [*] Don't use /usr        #这项必选选上,否则BusyBox默认安装路径是/usr,原/usr下的东西可能会被覆盖了

        Applets links (as soft-links)  ---> 
     (./_install) BusyBox installation prefix
Busybox Library Tuning  --->
     [*] Command line editing
     (1024) Maximum length of input                  
     [*]   vi-style line editing commands              
     (15)  History size                   
     [*]   History saving                                    
     [*]   Tab completion                                     
     [*]     Username completion                              
     [*]   Fancy shell prompts
这两项必须选上,不然BusyBox将无法识别环境变量PS1里的参数。
Linux Module Utilities  ---> 
     [*] insmod                                                        
     [*]   Enable load map (-m) option                                  
     [*]     Symbols in load map                                         
     [*] rmmod                                                          
     [*] lsmod                                             
     [*]   Pretty output for 2.6.x Linux kernels                     
     [*] modprobe
     [ ]   Multiple options parsing                                 
     [ ]   Fancy alias parsing                                           
     [ ]   Blacklist support                                        
     ---   Options common to multiple modutils                   
     [ ] Support tainted module checking with new kernels            
     [ ] Support version 2.2.x to 2.4.x Linux kernels               
     [*] Support version 2.6.x Linux kernels
                  
     (/lib/modules) Default directory containing modules             
     (modules.dep) Default name of modules.dep 

保存退出 Busybox
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ make
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ make install
编译BusyBox时,可能会出现以下错误:
4.1、inotifyd出错
交叉编译busybox-1.11.1时,出现以下错误:
CC      miscutils/inotifyd.o
miscutils/inotifyd.c:31:27: linux/inotify.h: No such file or directory
miscutils/inotifyd.c: In function `inotifyd_main':
miscutils/inotifyd.c:61: error: `IN_ALL_EVENTS' undeclared (first use in this function)
miscutils/inotifyd.c:61: error: (Each undeclared identifier is reported only once
miscutils/inotifyd.c:61: error: for each function it appears in.)
miscutils/inotifyd.c:129: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:139: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:140: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:140: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:143: error: invalid application of `sizeof' to incomplete type `inotify_event'
miscutils/inotifyd.c:143: error: dereferencing pointer to incomplete type
make[1]: *** [miscutils/inotifyd.o] Error 1
make: *** [miscutils] Error 2 

网上说这是busybox的一个bug,解决方法:去掉对inotifyed的支持,具体步骤如下:
# make menuconfig
Miscellaneous Utilities  --->
    [ ]inotifyd
还有另一个bug是taskset,也要将它去掉,不然编译时又会出错。
Miscellaneous Utilities  --->
    [ ]taskset
4.2、启动时,BusyBox提示 "/bin/sh:can't access tty;job console turn off"
解决方法:
shell  --->
    [ ]Job Console
    [*]Cttyhack       

4.3、未定义ARPHRD_INFINIBAND
错误信息如下:
networking/interface.c:818: error: 'ARPHRD_INFINIBAND' undeclared here (not in a function)
make[1]: *** [networking/interface.o] Error 1
make: *** [networking] Error 2

通过查看内核源代码目录中的“include/linux/ifarp.h”文件可知“ARPHRD_INFINIBAND”的值为“32”。然后修改“networking/interface.c”文件,在其中添加:
#define ARPHRD_INFINIBAND 32  /* InfiniBand */

默认在 _install目录中生成基本的文件系统, 包括以下目录或文件bin、sbin、linuxrc该目录下包含了基本的 shell 命令.将编译好的BusyBox的_Install目录下的bin和sbin用tar命令打包复制到~/rootfs目录,解压后删除打包文件。
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ cd _install
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ ls
bin  linuxrc  sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ tar zcvf rootfs.tar.gz bin sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ ls
bin  linuxrc  rootfs.tar.gz  sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ mv rootfs.tar.gz ../../rootfs
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ ls
bin  linuxrc  sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ cd ../../rootfs
lingd@ubuntu:~/arm2410s/rootfs$ ls
bin  etc   lib      mnt   root           sbin  tmp  var
dev  home  linuxrc  proc  rootfs.tar.gz  sys   usr
lingd@ubuntu:~/arm2410s/rootfs$ tar zvxf rootfs.tar.gz
lingd@ubuntu:~/arm2410s/rootfs$ rm rootfs.tar.gz


5、lib库文件复制到rootfs/lib目录下(根据需要复制)
lingd@ubuntu:~/arm2410s/rootfs$ cd /opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR ld* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libc*.so* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libcrypt* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libgcc_s.so* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libm* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libpthread.so* ~/arm2410s/rootfs/lib



6、生成CramFS文件系统镜像文件CramFS.img
首先从http://sourceforge.net/projects/cramfs/下载cramfs-1.1.tar.gz
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cd ~/arm2410s
lingd@ubuntu:~/arm2410s$ tar zxvf cramfs-1.1.tar.gz
lingd@ubuntu:~/arm2410s$ cd cramfs-1.1
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls
COPYING  cramfsck.c  GNUmakefile  linux  mkcramfs.c  NOTES  README
lingd@ubuntu:~/arm2410s/cramfs-1.1$ make
gcc -W -Wall -O2 -g -I.   mkcramfs.c  -lz -o mkcramfs
gcc -W -Wall -O2 -g -I.   cramfsck.c  -lz -o cramfsck

在 cramfs-1.1目录下会出现两个bin文件mkcramfs和cramfsck
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls
COPYING   cramfsck.c   linux     mkcramfs.c  README
cramfsck  GNUmakefile  mkcramfs  NOTES

把他们copy到/usr/bin: 
lingd@ubuntu:~/arm2410s/cramfs-1.1$ sudo cp mkcramfs cramfsck /usr/bin
创建根文件系统的cramfs镜像
lingd@ubuntu:~/arm2410s/cramfs-1.1$ mkcramfs ../rootfs CramFS01.img
Directory data: 6020 bytes
Everything: 908 kilobytes
Super block: 76 bytes
CRC: 526c6bb5
warning: gids truncated to 8 bits (this may be a security concern)
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls
COPYING       cramfsck    GNUmakefile  mkcramfs    NOTES
CramFS01.img  cramfsck.c  linux        mkcramfs.c  README
测试一下刚生成的CramFS01.img:
lingd@ubuntu:~/arm2410s/cramfs-1.1$ sudo mount -o loop -t cramfs ~/CramFS01.img /mnt/usb
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls /mnt/usb
查看是否有bin、etc等目录

编译cramfs时出现如下错误:
mkcramfs.c:37:18: zlib.h: No such file or directory
mkcramfs.c: In function `write_superblock':
mkcramfs.c:392: warning: implicit declaration of function `crc32'
mkcramfs.c:392: error: `Z_NULL' undeclared (first use in this function)
mkcramfs.c:392: error: (Each undeclared identifier is reported only once
mkcramfs.c:392: error: for each function it appears in.)
mkcramfs.c: In function `do_compress':
mkcramfs.c:598: warning: implicit declaration of function `compress2'
mkcramfs.c:598: error: `Z_BEST_COMPRESSION' undeclared (first use in this function)
mkcramfs.c:599: error: `Z_OK' undeclared (first use in this function)
mkcramfs.c:600: warning: implicit declaration of function `zError'
mkcramfs.c: In function `main':
mkcramfs.c:824: error: `Z_NULL' undeclared (first use in this function)
make: *** [mkcramfs] Error 1

原因没安装zlib-devel包
在ubuntu软件源里zlib和zlib-devel叫做zlib1g zlib1g.dev
$ sudo apt-get install zlib1g
$ sudo apt-get install zlib1g.dev



参考文章
ARM嵌入式Linux系统开发技术详解 杨水清、张剑、施云飞等编著
使用mdev制作cramfs根文件系统 
http://hi.baidu.com/kkernel/blog/item/cf2d6845b917e836879473b3.html
飞凌OK-2440-III文件系统移植-------busybox+mdev
http://bbs.21ic.com/icview-155436-1-1.html
s3c2410平台linux2.6.22内核的文件系统移植总结
http://hi.baidu.com/hzau_wall_e/blog/item/76258afb58b6b5819e5146cc.html/cmtid/d4e418ee679a101cfdfa3cd4
linuxrc详解
http://blog.chinaunix.net/u1/38576/showart_444508.html
详解Linuxrc、rcS、rc.local、Profile
http://hi.baidu.com/wangy0919/blog/item/1e0bc18fd27f86f8513d92fb.html
使用Busybox制作CRAMFS文件系统成功
http://linux.chinaunix.net/techdoc/system/2008/08/20/1026770.shtml
关于根文件系统中命令行提示符的显示
免费格式转换工具实战指南:从参数调优到批量处理 格式转换是数据处理中的基础技术,其核心原理是通过编解码器实现不同文件格式间的相互识别与重构。在音视频处理、文档数字化等场景中,合理的参数配置能平衡文件质量与体积,提升工程效率。视频转换需关注分辨率、码率和帧率的协同设置,而批量处理则涉及文件命名规则与失败重试机制。针对FFmpeg等常用工具,掌握其核心参数调优能显著提升转换成功率。本文基于视频转码和PDF转换等高频需求,深入解析参数配置技巧与常见问题排查方案,帮助开发者规避格式兼容性陷阱,实现稳定高效的文件格式转换。 阅读详情

相关推荐

嵌入式开发实战:Cramfs镜像制作与U-Boot烧录全流程详解

在嵌入式系统开发中,文件系统选型是影响设备稳定性和存储效率的关键决策。针对资源受限的MCU或ARM平台,只读文件系统因其安全性和空间效率成为系统分区的理想选择。Cramfs(Compressed ROM File System)作为一种经过压缩的只读Linux文件系统,其核心原理是通过内核驱动按需透明解压文件到内存,既能显著节省Flash存储空间,又能杜绝运行时意外修改导致设备变砖的风险。这种技术特性使其特别适合作为嵌入式产品的量产标准方案,广泛应用于需要高鲁棒性的工业控制、物联网设备等场景。本文聚焦于Cr

weixin_30764771的博客 339

使用BusyBox制作linux根文件系统

<br />使用BusyBox制作linux根文件系统(CramFS+mdev) <br />操作系统:Ubuntu9.04<br />内核版本:linux-2.6.24.7  <br />开发板:博创arm2410s    <br />交叉编译工具:arm-linux-gcc-4.1.1 <br />BusyBox:busybox-1.11.1       <br />CramFS:CramFS-1.1<br /> <br />注意:由于要制作的根文件系统使用了mdev(BusyBox简化版的udev),

babyfans的专栏 2086

arm -版本busybox

arm -版本busybox 的docker打包镜像 直接 docker load < 加载镜像

linux下文件系统的制作

一、 文件系统简介 嵌入式系统中常用文件系统包括有cramfs、JFFS2、NFS、initrd、yaffs2 以及squashfs。它们的特点如下: (1)、cramfs 和JFFS2 具有好的空间特性,很适合嵌入式产品应用。 (2)、cramfs 与squashfs 为只读文件系统。 (3)、squashfs 压缩率最高。 (4)、JFFS2 为可读写文件系统。 (5)、NFS 文件系统适用...

ProYuan的博客 1616

Python与Wind量化接口实战:从配置到数据提取全流程解析

本文详细解析了Python与Wind量化接口的实战应用,从环境配置到数据提取全流程。通过Anaconda管理Python环境,安装WindPy接口,实现历史行情、截面数据和实时行情的查询与优化。文章还提供了高级功能如批量查询、数据缓存策略及实战案例,帮助开发者高效构建量化分析框架。

omega的博客 1327

从零到一:基于GeneMark-ES/ET的新基因组注释实战指南

本文提供了一份基于GeneMark-ES/ET的新基因组注释实战指南。详细介绍了从环境搭建、数据准备到核心运行的全流程,重点解析了ES(从头预测)与ET(结合RNA-Seq证据)两种模式的选择与操作,并分享了Perl模块依赖、并行处理等常见问题的解决方案,帮助生物信息学研究者高效完成基因预测工作。

weixin_29266647的博客 209

BusyBox制作嵌入式Linux Cramfs根文件系统详解

BusyBox制作嵌入式Linux Cramfs根文件系统详解 开发环境:Ubuntu9.04 内核版本:Linux-2.6.24.7 开 发板 :FS2410 编 译 器:arm-linux-gcc-4.1.1 BusyBox:Busybox-1.11.1 CramFS :CramFS-1.1 注意:由于要制作的根文件系统使用了mdev(Busy

bugouyonggan的专栏 3050

抖音直播小风车跳转企业微信全攻略:企业号申请+落地页配置详解

本文详细解析了抖音直播小风车跳转企业微信的全流程,包括企业号申请、小风车配置和落地页优化。通过实战指南,帮助企业高效实现私域流量沉淀,提升直播转化率,特别适合电商和营销从业者参考。

weixin_29289821的博客 613

根文件系统实验

 本实验完成如何构建自己所需要的根文件系统,包括初始化脚本、常用的命令、库文件及设备等。1. 创建空的目录树         首先创建一个空的目录树,来作为根文件系统的基础。mkdir rootfscd rootfs/mkdir bin dev etc lib mnt proc sbin sys tmp usr

chenglian_999的专栏 1183

RV1126双摄IMX577驱动移植避坑:从RK3588到RV1126的dts配置与内存崩溃解决实录

本文详细记录了在RV1126平台上移植RK3588的IMX577双摄驱动的完整过程,重点解决了dts配置与内存崩溃问题。通过分析硬件架构差异、驱动移植关键点及CMA内存越界问题,提供了两种有效解决方案,并分享了双摄同步优化与网络调试的实战经验,为嵌入式视觉系统开发提供实用参考。

weixin_42641741的博客 405

电流镜结构实战:从零理解MOS管偏置电路设计(附吴金课程补充)

本文深入解析电流镜结构在MOS管偏置电路设计中的关键作用,从基本原理到实战应用全面覆盖。通过分析偏置电路的核心原理、破解设计难题的实用技巧,以及进阶优化策略,帮助工程师掌握这一模拟电路设计的核心技术。特别适合需要理解电流镜结构和基准电路设计的读者参考学习。

ujm5678901的博客 256

根文件系统中相关配置文件的介绍

<br />使用BusyBox制作linux根文件系统(CramFS+mdev)<br /> <br />注意:由于要制作的根文件系统使用了mdev(BusyBox简化版的udev),因此,需要内核支持sysfs、procfs和ramfs(tmpfs)文件系统以及hotplug(uevent)事件机制。<br /><br />以下操作都是在rootfs目录下<br /><br />1、建立根文件系统的目录框架和相关配置文件<br />目录框架为:<br />bin  dev  etc  lib  mnt 

shuangxi2010的专栏 1036

OpenBCI脑电帽硬件DIY与低成本搭建实战

本文详细介绍了如何通过第三方兼容硬件和开源设计,低成本DIY一套功能完备的OpenBCI脑电采集系统。从硬件选购、组装、软件配置到信号调试,提供了完整的实战指南,将总成本控制在千元级别,使脑机接口技术对爱好者、学生和研究者变得更加触手可及。

weixin_29322855的博客 785

移植根文件系统到linux内核 s3c2440,u-boot-2011.06在基于s3c2440开发板的移植之引导内核与加载根文件系统...

三、根文件系统的制作我们利用busybox来制作根文件系统1.在下列网站下载busybox-1.15.0.tar.bz2在当前目录下解压busyboxtar -jxvf busybox-1.15.0.tar.bz22.配置编译busybox使用menuconfig来配置busybox:make menuconfig修改下列内容:Busybox Settings --->Build Opt...

weixin_31220971的博客 249

在Simulink中搭建一个基于IoT设备间通信协议栈的仿真模型

物联网(IoT)设备间的通信协议栈仿真对于理解不同层级的协议如何协同工作,以及优化网络性能至关重要。通过Simulink结合MATLAB的强大功能,我们可以模拟和分析从物理层到应用层的完整通信过程。下面详细介绍如何使用Simulink进行IoT设备间通信协议栈的仿真。

amy_mhd的博客 156

Ubuntu 系统下安装 OpenClaw(原 Clawdbot)的详细指南

Ubuntu 系统下安装 OpenClaw(原 Clawdbot)的详细指南

Science prince的博客 3535

ARM根文件系统制作

ARM根文件系统制作

huangbo201102的专栏 2324

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

上一篇: 移植2440遇到的错误
下一篇: 外部晶振(external crystal)和外部时钟(external clock)有什么区别?
flymachine
博客等级 码龄23年 253粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值