Yaffs2根文件系统制作

Yaffs2根文件系统制作

[email protected]

http://blog.csdn.net/zouxy09

 

环境:

   交叉编译环境:4.3.3 (天嵌科技提供,存放路径/home/xiaoyi/4.3.3)

开发平台:TQ2440

注:这里有一些东西没有提到,请结合天嵌提供的linux移植手册来进行移植

   

、编译busybox(主要是获得linux下的工具包和函数库,如bin、sbin下的工具)

获取busybox源码busybox-1.16.0.tar (http://www.busybox.net/downloads/)

置于目录/home/xiaoyi里

#tar jxvf busybox-1.16.0.tar.bz2

#cd busybox-1.16.0

#vi Makefile

将164行改为CROSS_COMPILE = arm-linux- 将190行改为ARCH = arm

(每拿到一个源码包,编译前要编辑主目录下的Makefile,把交叉编译工具和适用架构改一下,再针对本板资源进行配置)

保存推出进入配置菜单

#make menuconfig    

在busybox编译里busybox settings->busybox library tuning->username completion、fancy shell prompts选上这两项,否则在终端显示的是[\u@\h \W]# 而不是[root@xiaoyi/]#

#make

#make install

在busybox-1.17.2的根目录下出现了一个_install目录在该目录下又有三个目录bin sbin usr 和一个链接文件 linuxrc  。前三者是控制台的工具目录,后者是一个指向到/bin/busybox的链接文件,在uboot的启动参数中,bootargs=noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,初始化内核后挂载文件系统后进入的第一进程init,就加载busybox这个shell工具集,这样才可以顺利使用ls等命令

    想要查看uboot参数,可以启动uboot下载模式,然后看菜单选择[0] Set the boot parameters;再选择接下来的选项即可

    天嵌的uboot启动参数如下:

bootargs=noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0

bootcmd=boot_zImage

bootdelay=0

baudrate=115200

ethaddr=0a:1b:2c:3d:4e:5f

ipaddr=192.168.1.6

serverip=192.168.1.8

netmask=255.255.255.0

stdin=serial

stdout=serial

stderr=serial

mtdids=nand0=nandflash0

mtdparts=mtdparts=nandflash0:256k@0(bios),128k(params),128k(toc),512k(eboot),1024k(logo),3m(kernel),-(root)

partition=nand0,0

mtddevnum=0

mtddevname=bios

 

Environment size: 423/131068 bytes

 

二、创建根文件系统必要的目录

     回到/home/xiaoyi目录下创建根文件系统必要的目录

#mkdir root_fs

#cd root_fs

将刚才生成的三个目录bin sbin usr和一个链接文件linuxrc考到目录root_fs下(要注意要全部一起拷,不能单个单个文件夹或文件拷,运用类似下面的指令,我的好像就是单个拷贝,导致我的文件系统移植失败的,我也不知道原因是什么)

#cp -rf ../busybox-1.16.0/_install/* ./ 

  创建根目录下的一级目录,由于是2.6的内核,所以sys是需要的

#mkdir dev etc home lib mnt opt proc root sys tmp var

创建几个必要的二级目录

#mkdir usr/lib usr/share

#mkdir etc/rc.d

#mkdir var/lib var/lock var/run var/tmp

 

三、创建必要文件

(1) 获取库文件(我的交叉编译工具链放在目录 /home/xiaoyi下的)

#cp -rf /home/xiaoyi/4.3.3/arm-none-linux-gnueabi/libc/armv4t/lib/*so* lib -a

(2)将主机 etc 目录下的passwd、group、shadow文件拷贝到 root_fs/etc目录下

#cp -f /etc/passwd /etc/group /etc/shadow etc

将目录/home/xiaoyi/busybox-1.16.0/examples/bootfloppy/etc下的所有文件拷贝到root_fs/etc下。在这个目录下有三个文件fstab, inittab, profile和一个目录init.d,

在目录init.d中有一个文件rcS。

#cp -rf ../busybox-1.16.0/examples/bootfloppy/etc/* etc

在目录etc下创建文件mdev.conf。 mdev是?v的一个简化版本,我们可以通过文件mdev.conf自定义一些设备节点的名称或链接来满足特定的需要,但在此处让它为空。

#touch etc/mdev.conf

(3)创建两个设备文件dev/console dev/null。

在linux内核源码文件init/main.c中有打开设备文件dev/console的操作如下:

static noinline int init_post(void)

__releases(kernel_lock)

{

………………………………

if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)

printk(KERN_WARNING "Warning: unable to open an initial console.\n");

………………………………

}

内核启动执行到这里时mdev还没有构建dev目录,如果没有创建设备文件dev/console就将会打印警告Warning: unable to open an initial console。

在内核启动的过程中要将产生的一些垃圾信息丢弃就需要空设备dev/null。

#mknod dev/console c 5 1  /*字符设备,主从设备号分别是5、1*/

#mknod dev/null c 1 3

 

四、几个必要文件的修改

     在启动过程中bootloader会传递参数init=/linuxrc给内核的 main( )函数,所以在文件系统被挂在后,运行的第一个程序是linuxrc,而linuxrc是一个指向/bin/busybox的链接文件,也就 是说文件系统被挂在后运行的第一个程序是busybox。Busybox首先会解析文件/etc/inittab,这个文件中存放的是系统的配置信息,这 些配置信息指明了接下来将要启动那些程序。

(1)修改文件etc/inittab如下(设定了系统在各状态下要运行的文件)

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

tq2440_serial0::askfirst:-/bin/sh

::ctrlaltdel:/sbin/reboot

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

/etc/inittab 文件中每个条目用来定义一个子进程,并确定它的启动方法,格式如下 (参数可以为空,但是:冒号不可以省略)

<id>:<runlevels>:<action>:<process>

<id>:表示这个进程要使用的控制台(即标准输入、标准输出、标准错误设备)。如果省 略,则使用与init进程一样的控制台。

<runlevels>:运行等级,对于Busybox init程序,这个字段没意义,可以省略。

<action>:表示init程序如何控制这个子进程,

<process>: 要执行的程序,它可以是可执行程序,也可以是脚本

 

文件etc/inittab配置条目说明如下:

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

启动系统初始化文件/etc/init.d/rcS。字段sysinit表明文件/etc/init.d/rcS在系统启动后最先执行,并且只执行一次,init进程等待它结束才继续执行其它动作。

(脚本文件名一般为rc,后缀S代表单用户运行级别脚本)

tq2440_serial0::askfirst:-/bin/sh

在串口tq2440_serial0上启动askfirst动作的shell。 S3C2410的串口名在/dev下是s3c2410_serialx。此时还没有移植自己的内核,用天嵌科技的内核所以串口名为 tq2440_serial0。askfirst表明init进程先输出 “Please press Enter to actvie this console”,等用户输入回车键之后才启动-/bin/sh。

::ctrlaltdel:/sbin/reboot

     当按下Ctrl+Alt+Delete组合键时,init重启执行程序。字段ctrlaltdel表明当按下Ctrl+Alt+Delete组合键时,执行相应的进程。

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

     告诉init在关机时运行umount命令卸载所有的文件系统,如果卸载失败,试图以只读方式重新挂载。字段shutdown表明在重启关闭系统命令时执行相应进程。

(2)当解析完文件etc/inittab后就将启动这些进程,首先要执行的是启动脚本etc/init.d/rcS。

修改文件etc/init.d/rcS如下:(此文件是“etc/inittab”中设定的系统初始化时使用的脚本,需要注意此文件需要有运行权限。)

#! /bin/sh

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

runlevel=S

prevlevel=N

umask 022

export PATH runlevel prevlevel

/bin/hostname xiaoyi

echo "----------mount all----------"

/bin/mount -a

echo /sbin/mdev>/proc/sys/kernel/hotplug

mdev -s

echo "**************************************"

echo "**************************************"

echo "Kernel version:linux-2.6.30.4"

echo "Date:2011.03.24"

echo "**************************************"

说明如下:

#! /bin/sh  用busybox的shell

PATH=/sbin:/bin:/usr/sbin:/usr/bin//shell命令的搜索路径环境变量

runlevel=S  //运行在单用户模式singal

prevlevel=N //前一个级别为n表示没有前一个级别none

umask 022  //权限位掩码,表示新建文件文件的默认属性-022

export PATH runlevel prevlevel //将设置的变量导出到环境中

/bin/hostname –F /etc/hostname //主机名,xiaoyi将出现在shell提示符中[root@xiaoyi/]#

/bin/mount -a  //将文件etc/fstab中指明的文件系统挂载到对应挂载点上

echo /sbin/mdev>/proc/sys/kernel/hotplug  //用mdev来处理内核的热插拔事件。

当有热插拔事件产生时, 内核就会调用位于/sbin目录的 mdev。 这时 mdev通 过环境变量中的 ACTION 和 DEVPATH,(这两个变量是系统自带的)来确定此次热插拔事件的动作以及影响了/sys 中的那个目录。接着会 看看这个目录中是否有“dev”的属性文件,如果有就利用这些信息为 这个设备在/dev 下创建设备节点文件。

 

mdev -s //建立dev目录。以‘-s’为参数调用位于/sbin 目录下的 mdev(其实是个链接,作用是传递参数给/bin目录下的busybox 程序并调用它) ,mdev扫描 /sys/class 和/sys /block中所有的类设备目录,如果在目录中含有名为“dev”的文件,且文件中包含的是设备号,则 mdev 就利用这些信息为这个设备在/dev下 创建设备节点文件。一般只在启动时才执行一次  “mdev -s” 。

(3)修改文件etc/fstab如下:(文件中提供了要自动挂载的对象)

#device    mount-point     type      option     dump   fsck   order

proc          /proc        proc     defaults    0        0 

none          /tmp        ramfs    defaults    0        0 

sysfs         /sys          sysfs    defaults    0        0 

mdev          /dev        ramfs    defaults    0        0 

    在系统启动初始化文件/etc/init.d/rcS中有执行挂载命令/bin/mount -a ,这便是将文件etc/fstab中指定的文件系统挂载到对应的挂载点上。这些文件系统的挂在是执行mdev -s命令建立dev目录的前提。

(4)在启动脚本etc/init.d/rcS执行完后将在串口tq2440_serial0启动一个shell。Shell启动过程中会根据文件/etc/profile配置登陆环境。

文件/etc/profile修改如下:

USER=" 'id -un' " 

LOGNAME=$USER 

PS1='[\u@\h \W]#' 

PATH=$PATH 

HOSTNAME='/bin/hostname' 

export USER LOGNAME PS1 PATH

具体说明:

profile文件会告诉shell使用什么语言,什么shell,命令的搜索路径等等。

USER="id -un"  //获取用户名id-un与whoami命令有相同的功能,打印用户名

PS1='[\u@\h \W]#'  //PS1指定sh提示符的格式在本环境下将是[root@xiaoyi]#  

HOSTNAME 设置为/bin/hostname的命令输出,获取主机名

export USER LOGNAME PS1 PATH 将这些变量导出到环境。

PS1:提示符的设置

   

    PS1(是数字1而不是字母l),每个版本bash的PS1变量内的特殊符号可能有些小的差异,你可以先man bash 一下。下面是FC4环境下默认的特殊符号所代表的意义:

\d   :代表日期,格式为weekday month date,例如:"Mon Aug 1"

\H :完整的主机名称。例如:我的机器名称为:fc4.linux,则这个名称就是fc4.linux

\h :仅取主机的第一个名字,如上例,则为fc4,.linux则被省略

\t :显示时间为24小时格式,如:HH:MM:SS

\T :显示时间为12小时格式

\A :显示时间为24小时格式:HH:MM

\u :当前用户的账号名称

\v :BASH的版本信息

\w :完整的工作目录名称。家目录会以 ~代替

\W :利用basename取得工作目录名称,所以只会列出最后一个目录

\# :下达的第几个命令

\$ :提示字符,如果是root时,提示符为:#   ,普通用户则为:$

默认的PS1内容为: '\[\u@\h\W\]\$' ,所以默认的提示符就是: [root@linux ~]#。

 

(5)在用户登录时将在/etc下寻找三个文件passwd ,shadow, group匹配相关信息。

这三个文件修改如下:

/etc/passwd

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

nobody:x:99:99:Nobody:/:/sbin/nologin

通常在Linux系统中,用户的关键信息被存放在系统的/etc/passwd文件中,系统的每一个合法用户账号对应于该文件中的一行记录。这行记录定义了每个用户账号的属性。

在该文件中,每一行用户记录的各个数据段用“:”分隔,分别定义了用户的各方面属性。各个字段的顺序和含义如下:

  注册名:口令:用户标识号:组标识号:用户名:用户主目录:命令解释程序shell

  (1)注册名(login_name):用于区分不同的用户。在同一系统中注册名是唯一的。在很多系统上,该字段被限制在8个字符(字母或数字)的长度之内;并且要注意,通常在Linux系统中对字母大小写是敏感的。这与MSDOS/Windows是不一样的。

  (2)口令(passwd):系统用口令来验证用户的合法性。超级用户root或某些高级用户可以使用系统命令passwd来更改系统中所有用户的口令,普通用户也可以在登录系统后使用passwd命令来更改自己的口令。

  现在的Unix/Linux系统中,口令不再直接保存在passwd文件中,通常将passwd文件中的口令字段使用一个“x”来代替,将/etc /shadow作为真正的口令文件,用于保存包括个人口令在内的数据。当然shadow文件是不能被普通用户读取的,只有超级用户才有权读取。

  此外,需要注意的是,如果passwd字段中的第一个字符是“*”的话,那么,就表示该账号被查封了,系统不允许持有该账号的用户登录。

  (3)用户标识号(UID):UID是一个数值,是Linux系统中唯一的用户标识,用于区别不同的用户。在系统内部管理进程和文件保护时使用UID字段。在Linux系统中,注册名和UID都可以用于标识用户,只不过对于系统来说UID更为重要;而对于用户来说注册名使用起来更方便。在某些特定目的下,系统中可以存在多个拥有不同注册名、但UID相同的用户,事实上,这些使用不同注册名的用户实际上是同一个用户。

  (4)组标识号(GID):这是当前用户的缺省工作组标识。具有相似属性的多个用户可以被分配到同一个组内,每个组都有自己的组名,且以自己的组标识号相区分。像UID一样,用户的组标识号也存放在passwd文件中。在现代的Unix/Linux中,每个用户可以同时属于多个组。除了在passwd文件中指定其归属的基本组之外,还在/etc/group文件中指明一个组所包含用户。

  (5)用户名(user_name):包含有关用户的一些信息,如用户的真实姓名、办公室地址、联系电话等。在Linux系统中,mail和finger等程序利用这些信息来标识系统的用户。

  (6)用户主目录(home_directory):该字段定义了个人用户的主目录,当用户登录后,他的Shell将把该目录作为用户的工作目录。在Unix/Linux系统中,超级用户root的工作目录为/root;而其它个人用户在/home目录下均有自己独立的工作环境,系统在该目录下为每个用户配置了自己的主目录。个人用户的文件都放置在各自的主目录下。

  (7)命令解释程序(Shell):Shell是当用户登录系统时运行的程序名称,通常是一个Shell程序的全路径名,如/bin/bash。为了阻止一个特定用户登录系统,可用/dev/null作为其shell,或例子中的/sbin/nologin。

  需要注意的是,系统管理员通常没有必要直接修改passwd文件,Linux提供一些账号管理工具帮助系统管理员来创建和维护用户账号。

/etc/group

root:x:0:root

bin:x:1:root,bin,daemon

daemon:x:2:root,bin,daemon

ftp:x:50:

nobody:x:99:

各标识符意义如下:

群组名称:群组密码:群组ID:支持的用户名称

X表示密码也存于shadow中了,例如第三行表示的意义如下:

Root,bin,daemon用户都属于daemon这个群组,GID为2,如果想要把xiaoyi用户添加到这里,只要在后面添加,xiaoyi即可,注意不要空格

/etc/shadow

root:$6$hnswPTgxzFaZHlLl$WMMV0Av6O6c4RA4pwpVSgcKSiURhUlP5dxF3/MKEZlGzNXhoWMQeZA1rdf1z7VQbrrmOZe7YHw1rIQmAc8BNK/:14819:0:99999:7:::

bin:*:14715:0:99999:7:::

daemon:*:14715:0:99999:7:::

ftp:*:14715:0:99999:7:::

nobody:*:14715:0:99999:7:::

 这个文件用来保存各用户和群的密码。意义如下:

用户名称:和passwd的相同;密码:经过加密的密码,如第一个字符是*,则表示该用户不会被登入,其他的是一些更改密码的日期限制,在这里不做解析。

最后是“etc/hostname”文件,此文件在“etc/init.d/rcS”文件中设定用来提供主机名称。

 

五、制作yaffs2根文件系统镜像

    用天嵌科技提供的yaffs2文件系统镜像制作工具mkyaffs2image(也可以到网上下载),制作2.6的yaffs2的镜像工具(针对Nand Flash是128MB到1GB的)。该工具已添加在/usr/local/sbin中,且该文件夹已经存在于环境变量中,所以可以直接使用。若不存在,则需要下载yaffs的源码包(cvs-root.tar),解压后进入yaffs2/utils/下,再make一下,则会在本目录下生成该工具,此时要用./mkyaffs2image才可以运行。

工具使用格式:

工具名 文件系统目录 镜像名

#mkyaffs2image root_fs root_fs.bin

 

六、将根文件系统镜像下载到nand flash并启动

启动信息如下:

Start Linux ...

Copy linux kernel from 0x00200000 to 0x30008000, size = 0x00300000 ... Copy Kernel to SDRAM done,NOW, Booting Linux......

Uncompressing Linux................................................................................................................. done, booting the kernel.

..................

 

[root@xiaoyi/]#

 

移植过程出现的问题:

1、移植网卡驱动没事。但记住每次重新编译文件系统时,必须把busybox下的_install下的文件一起拷贝到根目录下,覆盖原来的即可

 

2、移植usb时,可以同时参考文档《Linux下的硬件驱动——USB设备》这里面把usb说得很不错。另外我的移植与天嵌的不同在于,我的u盘被linux映射为SCSI的sda时,底下并没有分区了,也就是没有sda1了,不过同样可以mount到udisk中使用。

在使用U盘或存储卡时,我该mount /dev/sda还是/dev/sda1呢?

这是一个历史遗留问题。存储卡最初尺寸很小,很多厂商在使用时,就直接使用存储,不含有分区表信息。而随着存储卡尺寸的不断扩大,它也就引入了类似硬盘分区的概念。例如/dev/hda你可以分成主分区hda1、hda2扩展分区hda3,然后把扩展分区hda3又分为逻辑分区hda5、hda6、hda7等。这样,通常的U盘就被分成一个分区sda1,类似把硬盘整个分区分成一个主分区hda1。

现在较多的数码设备也和windows一样,是把所有U盘容量分为一个,所以在对待U盘的时候,通常你mount的是sda1。但对于某些特殊的数码设备格式化的U盘或存储卡(目前我发现的是一款联想的支持模拟USB软盘的U盘和我的一个数码相机),你就要mount /dev/sda。因为它根本就没分区表(若mount /dev/sda1通常的效果是死掉)。其实,这些信息,只要你注意了/proc/partitions文件,都应该注意到的。

你可能感兴趣的:(linux,shell,user,工具,makefile)