精华内容
下载资源
问答
  • 周立功arm文件系统ZLG_FS.pdf 周立功arm文件系统ZLG_FS.pdf 周立功arm文件系统ZLG_FS.pdf 周立功arm文件系统ZLG_FS.pdf
  • ARM文件系统实现方法

    2008-08-06 22:35:39
    arm环境下对外设的访问例程
  • arm romfs文件系统介绍

    2013-04-08 22:08:11
    arm 的romfs文件系统介绍,让你更加体味romfs文件系统
  • 构建arm架构ubuntu根文件系统.pdf构建arm架构ubuntu根文件系统.pdf构建arm架构ubuntu根文件系统.pdf构建arm架构ubuntu根文件系统.pdf构建arm架构ubuntu根文件系统.pdf构建arm架构ubuntu根文件系统.pdf构建arm架构...
  • arm 上实现的文件系统

    2011-06-29 16:09:55
    arm实现的文件系统,在sd卡实现文件的新建,删除,等操作
  • 如果以上1、2没有问题,那么可以使用以下脚本,制作一个给ARM开发板使用的文件系统。可以自行定制使用,加入自己的Test demo。#!/bin/bash #yuanxin.yang develop 2015-07-05 #文件系统和Busybox的路径====>...

    1.Busybox源码请网上自行下载,编译方法请参考百度。

    2.交叉编译工具链的设置也请先设置好。

    如果以上1、2没有问题,那么可以使用以下脚本,制作一个给ARM开发板使用的文件系统。

    可以自行定制使用,加入自己的Test demo。

    #!/bin/bash
    #yuanxin.yang develop  2015-07-05
    
    #文件系统和Busybox的路径====>可自己定制
    FILESYSTEM=/Softwave/filesystem                  #定义自己制作的文件系统存放的位置
    BUSYBOX=/Softwave/arm/busybox-1.17.2			 #Busybox软体的位置
    LIBS=/usr/local/arm/4.5.1/arm-none-linux-gnueabi #交叉编译相关的库文件的位置
    
    #判断文件是否存在 如果存在 就删除
    if [ -d $FILESYSTEM ]
    then
        rm -rf $FILESYSTEM &>/dev/null
        mkdir $FILESYSTEM &>/dev/null 
    else
        mkdir $FILESYSTEM &>/dev/null 
    fi
    
    #拷贝busybox相关的文件
    if ! cp -rf  $BUSYBOX/_install/* $FILESYSTEM &>/dev/null
    then
        echo "cp busybox failed..."
        exit 1
    fi
    
    
    #拷贝库
    if ! cp -rf $LIBS/lib/ $FILESYSTEM/ &>/dev/null
    then
        echo "copy libs fair...."
        exit 1
    fi
    
    #拷贝etc
    if ! cp -rf $BUSYBOX/examples/bootfloppy/etc  $FILESYSTEM &>/dev/null
    then
        echo "copy etc fair..."
        exit 1
    fi
    
    #创建Linux相关目录
    cd $FILESYSTEM &>/dev/null
    mkdir boot mnt root sys var net proc tmp dev home opt &>/dev/null
    
    #修改配置文件
    echo > $FILESYSTEM/etc/fstab 
    
    #修改etc/profile文件
    echo "# /etc/profile: system-wide .profile file for the Bourne shells" > $FILESYSTEM/etc/profile
    echo "echo \"===========================\"" >> $FILESYSTEM/etc/profile
    echo "echo \"Welcom to Linux System\"" >> $FILESYSTEM/etc/profile
    echo "echo \"===========================\"" >> $FILESYSTEM/etc/profile
    echo "export PS1=\"[yuanxin@Linux \W] # \"" >> $FILESYSTEM/etc/profile
    
    #修改 etc/init.d/rcS
    echo "#! /bin/sh" > $FILESYSTEM/etc/init.d/rcS
    echo "/bin/mount -n -t proc  none /proc" >> $FILESYSTEM/etc/init.d/rcS 
    echo "/bin/mount -n -t sysfs none /sys " >> $FILESYSTEM/etc/init.d/rcS  
    echo "/bin/mount    -t ramfs none /dev " >> $FILESYSTEM/etc/init.d/rcS  
    echo "/bin/mount -n -t ramfs none /tmp " >> $FILESYSTEM/etc/init.d/rcS  
    echo "/sbin/mdev -s"                     >> $FILESYSTEM/etc/init.d/rcS   
    
    
    #配置nfs服务
    if ! grep "$FILESYSTEM" /etc/exports &>/dev/null
    then
        echo "/filesystem *(rw,sync,no_root_squash)" >> /etc/exports
    fi
    
    #启动服务
    iptables -F &>/dev/null
    service rpcbind restart 
    service nfs restart 
    
    echo "make filesystem ok....."
    
    exit 0


    展开全文
  • arm linux 根文件系统制作

    千次阅读 2016-08-24 11:24:21
    准备:创建rootfs目录,用于保存文件系统 #mkdir rootfs 1、在rootfs中创建一些必要的目录 #mkdir bin dev etc lib proc sbin sys usr mnt tmp var #mkdir usr/bin usr/lib usr/sbin lib/modules 2、创建设备文件...

    准备:创建rootfs目录,用于保存文件系统

    #mkdir rootfs
    


    1、在rootfs中创建一些必要的目录

    #mkdir bin dev etc lib proc sbin sys usr mnt tmp var
    #mkdir usr/bin usr/lib usr/sbin lib/modules


    2、创建设备文件

    #cd rootfs/dev
    #mknod -m 666 console c 5 1
    #mknod -m 666 null c 1 3


    3、加入配置文件(配置文件与体系结构无关)

    #cp etc/* rootfs/etc -rf


    4、进入自己的linux内核目录添加内核模块

    #cd .../linux
    #make modules ARCH=arm CROSS_COMPILE=arm-linux-
    #make modules_install ARCH=arm INSTALL_MOD_PATH=.../rootfs


    5、编译、安装busybox

    5.1、配置busybox

    #cd .../busybox
    #make menuconfig

    Busybox Settings->build Options->

    选中“Build BusyBox as a static binary”

    Cross Compiler prefix选项中填入arm-linux-


    Busybox Settings->Installation Options->

    选中“Don't use /usr”避免busybox被安装到宿主机的/usr目录下

    BusyBox installation prefix中填入/xxx/rootfs(自己rootfs的绝对地址),表明编译后busybox的安装位置

    退出并保存

    5.2、编译busybox

    #make
    #make install


    进入自己的根文件系统目录.../rootfs

    #cd .../rootfs
    #ls
    #bin  dev  etc   lib  linuxrc  mnt  proc  sbin  sys  tmp  usr  var
    

    1、在rootfs/中创建一个到rootfs/bin的软连接(千万别连到宿主机的/bin)
    #cd .../rootfs
    #ln -s ./bin/busybox init
    #ls
    #bin  dev  etc  init  lib  linuxrc  mnt  proc  sbin  sys  tmp  usr  var

    到此根文件系统制作完毕.../rootfs便是根文件系统的目录


    展开全文
  • 1.设置登录时需要用户和用户密码,在/etc/inittab文件中添加: ::respawn:/sbin/getty -L ttyPS0 115200 vt100 或 ::respawn:-/bin/login 2.设置登录时不需要用户和用户密码,在/etc/inittab文件中添加: ttyPS...

    1.设置登录时需要用户和用户密码,在/etc/inittab文件中添加:

    ::respawn:/sbin/getty -L ttyPS0 115200 vt100  或  ::respawn:-/bin/login

    2.设置登录时不需要用户和用户密码,在/etc/inittab文件中添加:

    ttyPS0::respawn:-/bin/ash

    3.用MD5修改用户密码,例如修改root的密码为123:

    输入命令:openssl passwd -1 123 

    生成md5码:$1$Cv0y/PAE$xa6DD/dWK4Sgcem4zS9jM1

    4.将生成的md5码修改/etc/shadow文件中的密码:

    root:$1$Cv0y/PAE$xa6DD/dWK4Sgcem4zS9jM1:17177:0:99999:7:::

    每一行给一个特殊帐户定义密码信息,每个字段用 : 隔开。 
    字段 1 定义与这个 shadow 条目相关联的特殊用户帐户。 
    字段 2 包含一个加密的密码。 
    字段 3 自 1/1/1970 起,密码被修改的天数 
    字段 4 密码将被允许修改之前的天数(0 表示“可在任何时间修改”) 
    字段 5 系统将强制用户修改为新密码之前的天数(1 表示“永远都不能修改”) 
    字段 6 密码过期之前,用户将被警告过期的天数(-1 表示“没有警告”) 
    字段 7 密码过期之后,系统自动禁用帐户的天数(-1 表示“永远不会禁用”) 
    字段 8 该帐户被禁用的天数(-1 表示“该帐户被启用”) 
    字段 9 保留供将来使用
     

    展开全文
  • ARM】制作Linux 文件系统

    千次阅读 2017-06-06 21:03:03
    1从零开始由busybox 建立文件系统 1文件系统在LINUX 中的结构图 2编译好kernel 3Uboot 状态下显示的环境设置信息 4开始busybox 生成文件系统 5完善文件系统 第一步 init 会调用etcinittab 文件并根据其做相应...

    文章目录


    #1从零开始由busybox 建立文件系统
    ##1.1文件系统在LINUX 中的结构图
    这里写图片描述
    ##1.2编译好kernel
    编译linux kernel的具体操作在之前文章讲过,下面简要提示一下。
    修改编译器PATH,指定寻找路径。
    cd kernel-2.6.13 (进入内核目录)
    cp config_n35 .config
    make (编译内核,假设已经设置好了)
    cd arch/arm/boot (进入生成的zImage 目录)
    mkimage.sh (产生有uboot 可以引导的uImage 内核文件)
    ##1.3Uboot 状态下显示的环境设置信息

    setenv bootcmd "tftp 30008000 uimage;bootm"
    setenv ipaddr 192.168.1.244
    setenv serverip 192.168.1.112
    setenv gatewayip 192.168.1.1
    setenv bootargs noinitrd root=/dev/nfs rw nfsroot=192.168.1.113:/home/wu-being/linux/my_nfs ip=192.168.1.244:192.168.1.114:192.168.1.1:255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
    

    我们启用NFS 方式装载文件系统,首先启动PC 上的NFS 服务器
    vi /etc/exports (添加你要装载的文件系统目录)
    /home/wu-being/linux/my_nfs 192.168.*.*(rw,sync,no_root_squash)
    /etc/rc.d/init.d/portmap restart
    /etc/rc.d/init.d/nfs restart
    然后启动内核,查看结果??
    ##1.4开始busybox 生成文件系统
    Busybox 是很多标准Linux 工具的单一可执行实现,它说明了一个问题,
    很多标准的linux 工具可以共享很多共同的元素。

    • 第1步:从www.busybox.net 下载最新的版本busybox1.18.4.

    • 第2步:解压并打补丁
      tar –jxvf busybox-1.18.4.tar.bz2

    wu-being@ubuntu:~/linux/bosybox$ l
    busybox-1.18.4/                 busybox-1.18.4-hush.patch*
    busybox-1.18.4-buildsys.patch*  busybox-1.18.4.tar.bz2*
    busybox-1.18.4-fuser.patch*
    wu-being@ubuntu:~/linux/bosybox$ patch -p0 <./busybox-1.18.4-buildsys.patch 
    wu-being@ubuntu:~/linux/bosybox$ patch -p0 <./busybox-1.18.4-fuser.patch 
    wu-being@ubuntu:~/linux/bosybox$ patch -p0 <./busybox-1.18.4-hush.patch 
    
    • 第3步:配制编译器路径,注意这个编译器版本要和编译Kernel的编译器版本同样。
    wu-being@ubuntu:~/linux/bosybox/busybox-1.18.4$ l /home/wu-being/linux/3.4.1/bin/
    arm-linux-addr2line*  arm-linux-gcc*        arm-linux-objcopy*
    arm-linux-ar*         arm-linux-gcc-3.4.1*  arm-linux-objdump*
    arm-linux-as*         arm-linux-gccbug*     arm-linux-ranlib*
    arm-linux-c++*        arm-linux-gcov*       arm-linux-readelf*
    arm-linux-c++filt*    arm-linux-gprof*      arm-linux-size*
    arm-linux-cpp*        arm-linux-ld*         arm-linux-strings*
    arm-linux-g++*        arm-linux-nm*         arm-linux-strip*
    wu-being@ubuntu:~/linux/bosybox/busybox-1.18.4$ export PATH=$PATH:/home/wu-being/linux/3.4.1/bin/    
    wu-being@ubuntu:~/linux/bosybox/busybox-1.18.4$ arm-linux-gcc(TAB)
    arm-linux-gcc        arm-linux-gcc-4.4.3  
    arm-linux-gcc-3.4.1  arm-linux-gccbug     
    wu-being@ubuntu:~/linux/bosybox/busybox-1.18.4$ arm-linux-gcc
    
    • 第4步:进入目录busybox-1.18.4/执行命令make defconfig (default config)
    • 第5步:指定构架和编译工具编译和安装busybox
      (1).先执行编译命令:make ARCH=arm CROSS_COMPILE=arm-linux-

    如果在32位Linux系统中编译,没修改下面三个问题可能不会报错,但也要修改后编译!

    如果没有定义ARPHRD_INFINIBAND,定义之
    vi networking/interface.c
    #define INFINIABAND_ALEN 20
    #define ARPHRD_INFINIBAND 20 //++
    
    如果没有定义IFLA_OPERSTATE,屏蔽它
    vi networking/libiproute/ipaddress.c
    #ifdef IFLA_OPERSTATE //++
    if (tb[IFLA_OPERSTATE]) {
    static const char operstate_labels[] ALIGN1 =
    "UNKNOWN\0""NOTPRESENT\0""DOWN\0""LOWERLAYERDOWN\0"
    "TESTING\0""DORMANT\0""UP\0";
    printf("state %s ", nth_string(operstate_labels,
    *(uint8_t*)RTA_DATA(tb[IFLA_OPERSTATE])));
    }
    #endif //++
    
    如果编译mkfs_ext2 工具错误,去掉它。
    make menuconfig --> Linux System Utilites --> mkfs_ext2 (disable) --->
    save and quit
    

    (2).命令编译成功后,执行安装命令:
    make ARCH=arm CROSS_COMPILE=arm-linux- install

    • 第6步:拷贝文件系统到NFS 能输出的目录
      mkdir /home/wu-being/linux/my_nfs
      cp -rf _INSTALL/* /home/wu-being/linux/my_nfs

    • 第7步:修改nfs 配置
      vi /etc/exports and append "/home/wu-being/linux/my_nfs 192.168..(rw,sync,no_root_squash)
      "
      /etc/init.d/nfs-kernel-server restart

    • 第8步:下载内核到目标板运行看结果
      配制板子文件系统目录,并保存。

    setenv bootargs noinitrd root=/dev/nfs rw nfsroot=192.168.1.113:/home/wu-being/linux/my_nfs ip=192.168.1.244:192.168.1.114:192.168.1.1:255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
    saveenv
    

    应该会看到文件系统已经Mount 成功,但是现实console 错误,应该是没有这个设备。

    VFS: Mounted root (nfs filesystem).
    mount_devfs_fs(): unable to mount devfs, err: -2
    Freeing init memory: 144K
    Warning: unable to open an initial console.
    Kernel panic - not syncing: No init found.  Try passing init= option to kernel.
    
    • 第9步:建立串口设备
      建立dev和lib目录,并在文件系统的dev目录创建主设备号为5次设备号为1的console字符设备:mknod console c 5 1
      (不一定要创建这个console,文件系统启动后自动创建,当dev目录一定要建立来挂载)
    • 第10步:下载并启动内核显示如下
    VFS: Mounted root (nfs filesystem).
    Mounted devfs on /dev
    Freeing init memory: 172K
    Kernel panic - not syncing: No init found. Try passing init= option to kernel.
    

    看来init 不存在或不能运行.

    • 第11步:指定init
      ln -sf bin/busybox init
      (不一定要,只是缺少相关的lib文件)
    • 第12步:再启动内核
      init 还是不能运行,也许就是busybox 不能运行,用文件形式打开busybox发现是要一些库文件。
      从原来挂载成功的文件系统目录的Lib下拷贝所需库
      最后结果
      这里写图片描述
    • 第13步:再启动内核
      看看效果
      这里写图片描述
      缺失etc下面的文件,新建init.d目录,touch rcSchmod 777 rcS
      这里写图片描述
      再看
      这里写图片描述
    • 修改busybox源码
      这里写图片描述
      这里写图片描述
      重新编译,安装,覆盖
      这里写图片描述

    挂载成功。
    ##1.5完善文件系统
    ###第一步: init 会调用/etc/inittab 文件,并根据其做相应的操作。

    add file etc/inittab, the init will use it to initialize system
    ------
    ::respawn:-/bin/sh
    

    运行内核,显示OK

    VFS: Mounted root (nfs filesystem).
    Mounted devfs on /dev
    Freeing init memory: 172K
    / #
    / # ls
    bin dev etc init lib sbin usr
    / #
    

    ###第二步:可以手工做些设置

    mkdir proc
    mkdir sys
    mount -t proc proc /proc
    mount -t sysfs sysfs /sys
    mdev -s
    

    ###第三步:play MP3

    ./mplayer -ac mad yishengyouni.mp3
    

    这里写图片描述
    ###第四步:添加Login

    vi passwd and vi group (create tw files)
    adduser root
    modify passwd file and change its user id and group id to 0.
    passwd root (modify password)
    

    ####修改inittab 为:

    ::sysinit:/etc/rcS
    ::respawn:/bin/login
    ::shutdown:/bin/umount -a
    

    ####创造文件rcS

    mount -t proc proc /proc
    mount -t sysfs sysfs /sys
    mdev -s
    telnetd &
    

    #2Linux 文件系统结构
    Linux 下文件系统是对复杂系统进行合理抽象的一个经典的例子,它通过一套统一的接口函数对不同的文件进行操作(普通文件,字符设备文件,块设备文件和socket 文件)。

    • 索引节点(inode): 用来存储数据的信息,如大小,属主,归属和读写权限
      等。
    • 块(block): 存储数据。
      虚拟文件系统VFS(virtual File System)是Linux 内核层实现的一种构架,
      为用户空间提供统一的文件操作借口。

    这里写图片描述

    ##2.1ext2 文件系统的总体存储布局
    这里写图片描述
    ###2.1.1Block
    文件系统中存储的最小单位块(Block) ,一个块究竟多大在格式化时确定的,例如mke2fs 的-b 选项可以设定块大小为1024、2048 或4096 字节。
    ###2.1.2Boot block
    而上图中启动块(Boot Block) 的大小是确定的,就是1KB,启动块是由PC 标准规定的,用来存储磁盘分区信息和启动信息,任何文件系统都不能使用启动块。启动块BootBlock之后才是ext2 文件系统的开始。
    ###2.1.3Block Group:
    ext2 文件系统将整个分区划成n 个同样大小的块,多个块组成块组(Block
    Group) ,每个块组都由以下部分组成。
    ####Super Block:
    超级块 (Super Block)(占用一个块大小)描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次mount的时间等等。超级块在每个块组的开头都有一份拷贝(也就是说每个块组组开头1024 字节为超级快,内容相同,估计是出于安全考量)。占用每个块组的第一个块,共1024 字节,记录着magic(魔数),block_size(块大小),block_count(块数),block_per_group(每组的块数)等信息。
    ####GDT,Group Descriptor Table
    块组描述符表(GDT,Group Descriptor Table)(占用一个块大小)每个块组的块组描述符占用32 个字节(见下面),整个分区的块组的块组描述符连成一片放在一个块里面就组成了块组描述符表。每个块组描述符(GroupDescriptor) 存储一个块组的描述信息,例如在这个块组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode 和数据块还有多少个等等。
    和超级块类似,块组描述符表在每个块组的开头也都有一份拷贝,这些信息
    是非常重要的,一旦超级块意外损坏就会丢失整个分区的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因此它们都有多份拷贝。通常内核只用到第0 个块组中的拷贝,当执行e2fsck 检查文件系统一致性时,第0 个块组中的超级块和块组描述符表就会拷贝到其它块组,这样当第0 个块组的开头意外损坏时就可以用其它拷贝来恢复,从而减少损失。
    注意,硬盘分区上的所有这些 group descriptors 要能塞在一个 block 里
    面。也就是说 groups_count * descriptor_size 必须小于等于 block_size。
    知道了硬盘分区上一共有多少个 block group,我们就可以把这么多个
    group descriptors 读出来了。先来看看 group descriptor 是什么样子的。

    struct ext3_group_desc
    {
    __u32 bg_block_bitmap; /* block 指针指向 block bitmap */
    __u32 bg_inode_bitmap; /* block 指针指向 inode bitmap */
    __u32 bg_inode_table; /* block 指针指向 inodes table */
    __u16 bg_free_blocks_count; /* 空闲的 blocks 计数 */
    __u16 bg_free_inodes_count; /* 空闲的 inodes 计数 */
    __u16 bg_used_dirs_count; /* 目录计数 */
    __u16 bg_pad; /* 可以忽略 */
    __u32 bg_reserved[3]; /* 可以忽略 */
    };
    

    每个 group descriptor 是 32 bytes 那么大。从上面,我们看到了三个
    关键的 block 指针,这三个关键的 block 指针,我们已经在前面都提到过了。
    ####块位图 (Block Bitmap)(占用一个块)
    一个块组中的块是这样利用的:数据块存储所有文件的数据,比如某个分
    区的块大小是1024 字节,某个文件是2049 字节,那么就需要三个数据块来存,即使第三个块只存了一个字节也需要占用一个整块;超级块、块组描述符表、块位图、inode 位图、inode 表这几部分存储该块组的描述信息。那么如何知道哪些块已经用来存储文件数据或其它描述信息,哪些块仍然空闲可用呢?块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit 代表本块组中的一个块,这个bit 为1 表示该块已用,这个bit 为0 表示该块空闲可用。
    这里写图片描述
    为什么用df 命令统计整个磁盘的已用空间非常快呢?因为只需要查看每
    个块组的块位图即可,而不需要搜遍整个分区(所有块组信息通过GDT形成了链表)。相反,用du 命令查看一个较大目录的已用空间就非常慢,因为不可避免地要搜遍整个目录的所有文件。
    这里写图片描述
    与此相联系的另一个问题是:
    在格式化一个分区时究竟会划出多少个块组呢?主要的限制在于块位图本身必须只占一个块。用mke2fs 格式化时默认块大小是1024 字节,可以用-b 参数指定块大小,现在设块大小指定为b 字节,那么一个块可以有8b 个bit,这样大小的一个块位图就可以表示8b 个块的占用情况,因此一个块组最多可以有 8b 个块,如果整个分区有s 个块,那么就可以有s/(8b)个块组。格式化时可以用-g 参数指定一个块组有多少个块,但是通常不需要手动指定,mke2fs 工具会计算出最优的数值。
    ####inode 位图(inode Bitmap)(占用一个块)
    和块位图类似,本身占一个块,其中每个bit 表示一个inode 是否空闲可用。
    ####inode 表(inode Table)(占用n 个块)
    我们知道,一个文件除了数据需要存储之外,一些描述信息也需要存储,
    例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l 命令看到的那些信息,这些信息存在inode 中而不是数据块中。每个文件都有一个inode,一个块组中的所有 inode 组成了inode 表。
    inode 表占多少个块在格式化时就要决定并写入块组描述符中,mke2fs 格式化工具的默认策略是一个块组有多少个8KB 就分配多少个inode。由于数据块占了整个块组的绝大部分,也可以近似认为数据块有多少个8KB 就分配多少个inode,换句话说,如果平均每个文件的大小是8KB,当分区存满的时候inode表会得到比较充分的利用,数据块也不浪费。如果这个分区存的都是很大的文件(比如电影),则数据块用完的时候inode 会有一些浪费,如果这个分区存的都是很小的文件(比如源代码),则有可能数据块还没用完inode 就已经用完了,数据块可能有很大的浪费。如果用户在格式化时能够对这个分区以后要存储的文件大小做一个预测,也可以用mke2fs 的-i 参数手动指定每多少个字节分配一个inode。
    ####数据块(Data Block)(n 个块)
    根据不同的文件类型有以下几种情况
    对于
    常规文件
    ,文件的数据存储在数据块中。
    对于目录,该目录下的所有文件名和目录名存储在数据块中,注意文件名保存在它所在目录的数据块中,除文件名之外,ls -l 命令看到的其它信息都
    保存在该文件的inode 中。注意这个概念:目录也是一种文件,是一种特殊
    类型的文件。
    这里写图片描述
    对于符号链接,如果目标路径名较短则直接保存在inode 中以便更快地查找,如果目标路径名较长则分配一个数据块来保存。
    ###2.1.4我们总结一下
    一个格式好的文件系统,分成固定大小的块,块组成块组,块的大小相
    同,每个块组的块数也相同;每个块组由超级快(记录块大小,有多少块,每个块组由多少块组成等),块组描述符表(由连贯的块组描述符组成,描述块位图,inode 位图和
    inode 表的地址等),块位图(哪个块使用了,哪个块空闲),inode位图(那个inode 占用了,那没有占用),inode 表(文件类型,权限,文件大小,创建/修改/访问时间和文件内容所在的块的地址)和数据块(文件的数据)组成。
    一个文件由文件内容和描述信息组成,文件内容保存在数据块中,文件描述信息保存在inode 中。
    知道了inode 的数值(ls –i),可以读出文件内容,如何,见下面.前面都准备好了以后,我们现在终于可以开始读取文件了。首先要读的,当然是文件系统的根目录。注意,这里所谓的根目录,是相对于这一个文件系统或者说硬盘分区而言的,它并不一定是整个 Linux 操作系统上的根目录。这里的这个 root 目录存放在一个固定的 inode 中,这就是文件系统上的 inode 2。需要提到 inode 计数同 block 计数一样,也是全局性质的。这里需要特别注意的是,inode 计数是从 1 开始的,而前面我们提到过 block 计数是从 0 开始,这个不同在开发程序的时候要特别留心。__
    那么,我们先来看一下得到一个 inode 号数以后,怎样读取这个 inode 中的用户数据。在 super block 中有一个字段 s_inodes_per_group 记载了每个block group 中有多少个 inode 。用我们得到的 inode 号数除以s_inodes_per_group,我们就知道了我们要的这个 inode 是在哪一个 block group 里面,这个除法的余数也告诉我们,我们要的这个 inode 是这个 block group 里面的第几个 inode;然后,我们可以先找到这个 block group 的 group descriptor,从这个 descriptor,我们找到这个 group 的 inode table,再从inode table 找到我们要的第几个 inode,再以后,我们就可以开始读取 inode中的用户数据了。
    这个公式是这样的:block_group = (ino - 1) / s_inodes_per_group。这里 ino 就是我们的 inode 号数。而 offset = (ino - 1) % s_inodes_per_group,这个 offset 就指出了我们要的 inode 是这个 block group 里面的第几个inode。找到这个 inode 之后,我们来具体的看看 inode 是什么样的。

    struct ext3_inode {
    __u16 i_mode; /* File mode */
    __u16 i_uid; /* Low 16 bits of Owner Uid */
    __u32 i_size; /* 文件大小,单位是 byte */
    __u32 i_atime; /* Access time */
    __u32 i_ctime; /* Creation time */
    __u32 i_mtime; /* Modification time */
    __u32 i_dtime; /* Deletion Time */
    __u16 i_gid; /* Low 16 bits of Group Id */
    __u16 i_links_count; /* Links count */
    __u32 i_blocks; /* blocks 计数 */
    __u32 i_flags; /* File flags */
    __u32 l_i_reserved1; /* 可以忽略 */
    __u32 i_block[EXT3_N_BLOCKS]; /* 一组 block 指针 */
    __u32 i_generation; /* 可以忽略 */
    __u32 i_file_acl; /* 可以忽略 */
    __u32 i_dir_acl; /* 可以忽略 */
    __u32 i_faddr; /* 可以忽略 */
    __u8 l_i_frag; /* 可以忽略 */
    __u8 l_i_fsize; /* 可以忽略 */
    __u16 i_pad1; /* 可以忽略 */
    __u16 l_i_uid_high; /* 可以忽略 */
    __u16 l_i_gid_high; /* 可以忽略 */
    __u32 l_i_reserved2; /* 可以忽略 */
    };
    

    我们看到在 inode 里面可以存放 EXT3_N_BLOCKS(= 15)这么多个 block 指
    针。用户数据就从这些 block 里面获得。15 个 blocks 不一定放得下全部的用
    户数据,在这里 ext3 文件系统采取了一种分层的结构。
    这组 15 个 block 指针的前 12 个是所谓的 direct blocks,里面直接存放的就是用户数据。
    第 13个 block,也就是所谓的 indirect block,里面存放的全部是 block 指针,这些 block 指针指向的 block 才被用来存放用户数据。
    第 14 个 block 是所谓的 double indirect block,里面存放的全是 block 指针,这些 block 指针指向的 block 也被全部用来存放 block 指针,而这些 block 指针指向的 block,才被用来存放用户数据。
    第 15 个 block 是所谓的 triple indirect block,比上面说的 double indirect block 有多了一层 block 指针。作为练习,读者
    可以计算一下,这样的分层结构可以使一个 inode 中最多存放多少字节的用户
    数据。
    一个 inode 里面实际有多少个 block,这是由 inode 字段 i_size 再通过
    计算得到的。i_size 记录的是文件或者目录的实际大小,用它的值除以 block
    的大小,就可以得出这个 inode 一共占有几个 block。现在我们已经可以读取 inode 的内容了,再往后,我们将要读取文件系统上文件和目录的内容。读取文件的内容,只要把相应的 inode 的内容全部读出来就行了;而目录只是一种固定格式的文件,这个文件按照固定的格式记录了目录中有哪些文件,以及它们的文件名,和 inode 号数等等。
    struct ext3_dir_entry_2 {
    __u32 inode; /* Inode 号数 /
    __u16 rec_len; /
    Directory entry length /
    __u8 name_len; /
    Name length /
    __u8 file_type;
    char name[EXT3_NAME_LEN]; /
    File name */
    };
    上面用到的 EXT3_NAME_LEN 是 255。注意,在硬盘分区上的 dir entry 不是固定长度的,每个 dir entry 的长度由上面的 rec_len 字段记录。
    问题:目录和文件名如何保存,如何读取?
    (目录只是一种固定格式的文件,可以“vim 目录”,看到这个目录文件的
    内容)
    ##2.2VFS 的建立
    经过前面的ext2 文件系统格式的介绍,我们起码知道了如何去获取文件系
    统的信息和如何读取文件内容。其中也建立了两个很重要的概念super block
    超级块和inode 节点信息,然后如果理解dentry(directory entry)概念就更
    好了。
    关于VFS,看开头的描述和逻辑图。
    在2.6 内核中,启动的过程中由vfs 建立的rootfs 根文件系统过程如下:
    kernel_start()
    |____start_kernel()
    |____vfs_caches_init()(fs/dcache.c)
    |____dcache_init()
    |____inode_init()
    |____files_init()
    |____mnt_init()
    | |____init_rootfs()
    | | |___register_filesystem(
    | | &rootfs_fs_type)
    | |_init_mount_tree()
    | |
    do_kern_mount()
    | (建立系统的根”/”)
    |____bdev_cache_init()
    |____chrdev_init()
    ###2.2.1第一步init_rootfs()
    init_rootfs() 通过调用 register_filesystem(&rootfs_fs_type)
    函数来完成 rootfs 文件系统注册的,其中rootfs_fs_type 定义如下:
    struct file_system_type rootfs_fs_type = {
    name: “rootfs”,
    read_super: ramfs_read_super,
    fs_flags: FS_NOMOUNT|FS_LITTER,
    owner: THIS_MODULE,
    }
    注册之后的 file_systems 链表结构如下图所示:
    ###2.2.2第二步而init_mount_tree()
    第二步而init_mount_tree() 是用来建立根“ / ” 目录的, 它会调用
    do_kern_mount(“rootfs”, 0, “rootfs”, NULL) 来挂载前面已经注册了的
    rootfs 文件系统。
    过程如下:

    1. 调用 alloc_vfsmnt() 函数在内存里申请了一块该类型的内存空间
      (struct vfsmount *mnt),并初始化其部分成员变量。(mnt : a vfs-internal representation of a mount point,主要记录装载信息)
    2. 调用 get_sb_nodev() 函数在内存中分配一个超级块结构 (struct
      super_block) sb,并初始化其部分成员变量,将成员 s_instances 插入到
      rootfs 文件系统类型结构中的 fs_supers 指向的双向链表中。
      (sb:描述文件系统信息,例如块大小、块组数,文件系统版本号、上次mount 的时间等等,参考前面ext2 文件系统的描述。)
    3. 通过 rootfs 文件系统中的 read_super 函数指针调用
      ramfs_read_super() 函数。还记得当初注册rootfs 文件系统时,其成员
      read_super 指针指向了 ramfs_read_super() 函数,参见上图(读取super
      block 信息填充其内容,参考前面ext2 的描述)
    4. ramfs_read_super() 函数调用 ramfs_get_inode() 在内存中分配了一
      个 inode 结构 (struct inode) inode,并初始化其部分成员变量,其中比较重要的有 i_op、i_fop 和 i_sb。
      inode->i_op = &ramfs_dir_inode_operations;
      inode->i_fop = &dcache_dir_ops;
      inode->i_sb = sb;
      (一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类
      型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l 命令看到的那些信息,这些信息存在inode 中而不是数据块中。每个文件都有一个inode,一个块组中的所有 inode 组成了inode 表。)
      这使得将来通过文件系统调用对 VFS 发起的文件操作等指令将被 rootfs
      文件系统中相应的函数接口所接管。
    5. ramfs_read_super() 函数在分配和初始化了 inode 结构之后,会调用
      d_alloc_root() 函数来为 VFS 的目录树建立起关键的根目录 (struct
      dentry)dentry,并将 dentry 中的 d_sb 指针指向 sb,d_inode 指针指向
      inode。(这里得到该文件系统的根,dentry directory entry)
      (对于目录,该目录下的所有文件名和目录名存储在数据块中,注意文件名保存在它所在目录的数据块中,除文件名之外,ls -l 命令看到的其它信息都保存在该文件的inode 中。注意这个概念:目录也是一种文件,是一种特殊类型的文件。
      例如“vim 目录“可以看到其内容)
    6. 将 mnt 中的 mnt_sb 指针指向 sb,mnt_root 和 mnt_mountpoint 指针
      指向 dentry,而 mnt_parent 指针则指向自身。
      结果建立了根目录如下:
      这里写图片描述
      2.6 内核中,调用过程如下:
      init_mount_tree()(fs/namespace.c)
      |____do_kern_mount(“rootfs”,0,“rootfs”,0)(fs/super.c)
      |____vfs_kern_mount(“rootfs”)(fs/super.c)
      |___mnt=alloc_vfsmnt(“rootfs”)(分配mnt 结构)
      |___get_sb(fs_type,…,ramfs_fill_super,mnt)
      | (就是调用rootfs_get_sb(),get_sb_nodev(),
      | ramfs_fill_super()分配sb 块)
      |___inode=ramfs_get_inode(sb,…)(分配inode)
      |___root=d_alloc_root(inode)
      (分配root 结构,填充’/'目录)

    **问题:**在上面的图中,如何建立一个目录,如何装载(mount)一个新的文件系统?
    ##2.3文件系统和进程的联系
    这里写图片描述
    ##2.4设备文件
    Linux 内核运行后,会在dev/目录自带生成一些设备文件。

    Please press Enter to activate this console. 
    / # ls
    a.out       etc         led_test    linuxrc     usr
    bin         hello       led_test.c  my_ko
    dev         hello.c     lib         sbin
    / # ls dev/
    buttons   ide       mem       port      scsi      urandom
    console   input     misc      ptmx      shm       usb
    fb        kmem      mtdblock  pts       sound     vc
    full      kmsg      nbd       random    tts       vcc
    i2c       loop      null      rd        tty       zero
    / # ls dev/ -l
    total 0
    crw-r-----    1 0        0         232,   0 Jan  1 00:00 buttons
    crw-------    1 0        0           5,   1 Jan  1 00:01 console
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 fb
    crw-rw-rw-    1 0        0           1,   7 Jan  1 00:00 full
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 i2c
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 ide
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 input
    crw-r-----    1 0        0           1,   2 Jan  1 00:00 kmem
    crw-r--r--    1 0        0           1,  11 Jan  1 00:00 kmsg
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 loop
    crw-r-----    1 0        0           1,   1 Jan  1 00:00 mem
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 misc
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 mtdblock
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 nbd
    crw-rw-rw-    1 0        0           1,   3 Jan  1 00:00 null
    crw-r-----    1 0        0           1,   4 Jan  1 00:00 port
    crw-rw-rw-    1 0        0           5,   2 Jan  1 00:00 ptmx
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 pts
    crw-r--r--    1 0        0           1,   8 Jan  1 00:00 random
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 rd
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 scsi
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 shm
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 sound
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 tts
    crw-rw-rw-    1 0        0           5,   0 Jan  1 00:00 tty
    crw-r--r--    1 0        0           1,   9 Jan  1 00:00 urandom
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 usb
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 vc
    drwxr-xr-x    1 0        0                0 Jan  1 00:00 vcc
    crw-rw-rw-    1 0        0           1,   5 Jan  1 00:00 zero
    / # ls dev/i
    i2c/    ide/    input/
    / # ls dev/i2c/ -l
    total 0
    crw-------    1 0        0          89,   0 Jan  1 00:00 0
    / # ls -l dev/input/
    total 0
    crw-r--r--    1 0        0          13,  64 Jan  1 00:00 event0
    crw-r--r--    1 0        0          13,  63 Jan  1 00:00 mice
    crw-r--r--    1 0        0          13,  32 Jan  1 00:00 mouse0
    crw-r--r--    1 0        0          13, 128 Jan  1 00:00 ts0
    crw-r--r--    1 0        0          13, 144 Jan  1 00:00 tsraw0
    / # 
    

    但实际的文件系统是没有这些设备文件的。

    wuchengbing@ubuntu:~/linux$ mv my_nfs my_nfs2
    wuchengbing@ubuntu:~/linux$ mv my_nfs_wu/ my_nfs
    wuchengbing@ubuntu:~/linux$ ls my_nfs
    a.out  dev  hello    led_test    lib      my_ko  usr
    bin    etc  hello.c  led_test.c  linuxrc  sbin
    wuchengbing@ubuntu:~/linux$ ls my_nfs/dev/
    wuchengbing@ubuntu:~/linux$ ll my_nfs/dev/
    total 8
    drwxrwxr-x 2 wuchengbing wuchengbing 4096 Apr 17 18:41 ./
    drwxrwxr-x 9 wuchengbing wuchengbing 4096 Apr 17 21:15 ../
    wuchengbing@ubuntu:~/linux$ 
    

    #3Kernel 启动过程和文件系统
    Kernel 启动过程中,初始化硬件和各种数据结构,并加载文件系统,进入用户态,运行文件系统中的程序,这个过程简述如下。Exec 函数族(execve 为其中一种)提供了一个在进程中启动另外一个程序执行的方法。它可以根据指定的文件名或目录找到可执行文件,并用它来取代原先调用进程的属性包括数据段,代码段和堆栈段等。在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。这里在执行execve 之前,进程1 还是共享着内核线程0 资源属性的内核线程。执行execve 后(即执行了用户空间的init 程序),此时,进程1 就拥有了自己的地址空间等属性,成为一个普通进程。
    Fork
    Init()—>call----->/etc/inittab------> /etc/rcS -------->login ----run shell

    #附录

    工具下载链接:
    https://github.com/1040003585/Mini24

    Wu_Being 博客声明:本人博客欢迎转载,请标明博客原文和原链接!谢谢!
    《【ARM】制作Linux 文件系统》
    http://blog.csdn.net/u014134180/article/details/72876310

    展开全文
  • 定制适用于ARM平台的Ubuntu rootfs(根文件系统

    万次阅读 热门讨论 2016-06-18 23:45:44
    0 背景 有一个很厉害的师兄针对我们实验室的需求设计了一块控制板,...前一段时间我在beaglebone官网下载了其提供的预编译好的根文件系统,修改挂载设置fstab文件后顺利启动,但是不能支持图形界面,不知是内核支持的原
  • debootstrap 制作arm64位根文件系统

    千次阅读 2019-09-07 20:32:07
    笔记中记录的是制作Debian 9的根文件系统,但是如果你跟着做一遍,Ubuntu的系统也是可以自行制作的,无非是在构建文件系统的时候把发行版本换成Ubuntu的发行版,还有镜像服务器。 制作根文件系统 环境 通过vm虚拟机...
  • 嵌入式根文件系统(基于arm

    千次阅读 2017-10-02 15:46:24
    1 根文件系统嵌入式可以包含多个文件系统,根文件系统是第一个,当linux启动的时候,第一个必须挂载的是根文件系统,若系统不能从指定设备上挂载根文件系统,则系统出错就退出。本文主要分以下两个部分说明根文件系统...
  • 创建基于arm的debian文件系统

    万次阅读 2015-01-15 10:35:19
    debian系统有针对arm分支的,在arm上跑debian系统可以用apt-get安装软件,避免繁琐的编译和重复创建文件系统的工作. 本例子使用z-turn的开发板为例. linux主机版本: root@v:i# lsb_release -a No LSB modules are ...
  • 详细描述了文件系统的制作过程,非常精细,有具体过程
  • 他在一个叫ramfs的cache实现上加了一层很薄的封装,其他内核开发人员编写了一个改进版tmpfs,这个文件系统上的数据可以写出到交换分区,而且可以设定一个tmpfs装载点的最大尺寸以免耗尽内存。initramfs就是tmpfs的...
  • ARM里面,启动MMU以后,我们编程看到的地址都是虚拟地址,经过MMU以后才是具体的物理地址。 4412在上电以后,MMU是关闭的,也就是说这个时候其实和单片机差不多,可以直接跑裸机程序(裸机程序,就是直接对CPU进行...
  • 太阳阵ARM如何制作根文件系统 首先新建 rootfs 目录, 将根文件系统压缩包 rootfs.tar.gz 文件和 mkfs.ubifs、ubinize两个工具及 ubinize.cfg 配置文件上传到虚拟机目录下  # mkdir rootfs # tar -zxvf ...
  • 零基础qemu模拟arm系统环境搭建

    千次阅读 2016-10-17 20:44:17
    零基础qemu模拟arm系统环境搭建
  • arm linux挂载nfs根文件系统

    千次阅读 2013-09-02 16:51:41
    一、在主机里安装nfs服务 ...在该文件中添加一行:/home/arm *(rw,sync,no_root_squash) 根据实际情况修改/home/arm为想要的路径就行了。 二、编译arm linux内核勾选nfs client [Filesystem] -> Mi...
  • ARM文件系统制作

    千次阅读 2011-04-24 11:25:00
    嵌入式根文件系统制作过程(For YC2440 Board)
  • ubuntu文件系统修改( for arm)

    千次阅读 2017-10-17 19:14:57
    ubuntu-rootfs.img for aarch64创建一个文件夹 ubuntu-mountmkdir ubuntu-mount将ubuntu-rootfs.img镜像挂载到ubuntu-mountmount ubuntu-rootfs.img ubuntu-mount进入ubunt-mount就可以看到文件系统的结构了。...
  • arm-linux(ubuntu) 根文件系统 制作

    千次阅读 2013-02-26 10:44:54
    【环境】 1:Ubuntu 10.10 2:u-boot-2010.03 3:linux-2.6.35 ...6:交叉编译器:arm-none-linux-gnueabi-gcc version 4.3.2 1)解压缩busybox tar xjvf busybox-1.17.3.tar.bz2   2)配置源码
  • ARM-Linux嵌入式系统启动流程

    千次阅读 多人点赞 2014-09-03 12:58:05
     根文件系统首先是一种文件系统,该文件系统不仅具有普通文件系统的存储数据文件的功能,但是相对于普通的文件系统,它的特殊之处在于,它是内核启动时所挂载(mount)的第一个文件系统,内核代码的映像文件保存在...
  • 非常详细的移植文档,可以让刚开始从事相关工作的人快速入门。
  • debian 文件系统制作 for ARM

    千次阅读 2016-09-12 20:54:32
    sudo cp /usr/bin/qemu-arm-static target-rootfs/usr/bin ~/debian_jessie$ sudo mount -o bind /dev/ target-rootfs/dev/ ~/debian_jessie$ sudo LC_ALL=C LANGUAGE=C LANG=C chroot target-rootfs dpkg --...
  • 搭建嵌入式ARM完整系统

    千次阅读 2019-02-12 20:38:56
    开发板运行机制内核文件系统; 文件管理系统 如下图,我们以mini2440的下载为参考: ​ 由烧写软件界面可以看到,我们在完成一个完整系统的移植时需要的成分也是以上三个。第一是引导程序,第二是内核系统,第三是...
  • 在前面的实验中我们将根文件系统制作到了SD卡上,每次启动系统时从SD卡启动,这样带来的问题是当我们主机要往开发板发送一些文件的时候必须将SD卡挂载然后将文件拷贝进去,然后在umount,这样的过程实在是太麻烦了,...
  • 一、编译Linux内核 下载Linux内核  推荐使用国内的镜像网站下载  下载完成后解压 修改Makefile  搜索CROSS_COMPILE交叉编译 ...= arm ...= arm-linux-gnueabi- ... 进入/arch/arm/查看官方支持的开发板    ...
  • arm文件格式

    千次阅读 2009-01-06 15:27:00
    说明:这个是一年前的工作了,现在把相关资料整理一下。... AMR文件结构示范图4. AMR帧头格式分析5. 异常帧分析6. AMR帧读取算法7. 参考资料1. 概述现在很多智能手机都支持多媒体功能,特别是音频和视频播放功

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 148,870
精华内容 59,548
关键字:

arm文件系统