u-boot-2010.12移植到2440(yaffs2文件系统移植)

    Yaffs2 文件系统的移植主要涉及到u-boot yaffs2 文件系统的烧写支持、linux 内核对yaffs2 文件系统的支持,以及yaffs2 文件系统的制作,现在我们按照从下到上的顺序来实现各部分的功能。本文重点参考黄刚的博文。

1 、实现 u-boot  yaffs/yaffs2 文件系统下载的支持。

注意:这里对Nand 的操作是基于MTD 架构方式。 

通常一个Nnad Flash 存储设备由若干块组成,1 个块由若干页组成。一般128MB 以下容量的Nand Flash 芯片,一页大小为528B ,被依次分为2 256B 的主数据区和16B 的额外空间;128MB 以上容量的Nand Flash 芯片,一页大小通常为2KB 。由于Nand Flash 出现位反转的概率较大,一般在读写时需要使用ECC 进行错误检验和恢复。

Yaffs/yaffs2 文件系统的设计充分考虑到Nand Flash 以页为存取单位等的特点,将文件组织成固定大小的段(Chunk) 。以528B 的页为例,Yaffs/yaffs2 文件系统使用前512B 存储 数据和16B 的额外空间存放数据的ECC 和文件系统的组织信息等( 称为OOB数据) 。通过OOB 数据,不但能实现错误检测和坏块处理,同时还可以避免加载 时对整个存储介质的扫描,加快了文件系统的加载速度。以下是Yaffs/yaffs2 文件系统页的结构说明:

 

     Yaffs 页结构说明 
============================================== 
    字节                    用途 
============================================== 
 0 - 511                存储数据 ( 分为两个半部 ) 
512 - 515               系统信息 
   516                  数据状态字 
   517                  块状态字 
518 - 519               系统信息 
520 - 522               后半部 256 字节的 ECC 
523 - 524               系统信息 
525 - 527               前半部 256 字节的 ECC 
==============================================

好了,在了解Nand Flash 组成和Yaffs/yaffs2 文件系统结构后,我们再回到u-boot 中。目前,在u-boot 中已经有对CramfsJffs2 等文件系 统的读写支持,但与带有数据校验等功能的OOB 区的Yaffs/Yaffs2 文件系统相比,他们是将所有文件数据简单的以线性表形式组织的。所以,我们只要在此基础上通过修改u-boot Nand Flash 读写命令,增加处理00B 区域数据的功能,即可以实现对Yaffs/Yaffs2 文件系统的读写支持。

实现u-boot Yaffs 或者Yaffs2 文件系统的读写支持步骤如下:

①、在include/configs/smdk2440.h 头文件中定义一个管理对Yaffs2 支持的宏和开启u-boot 中对Nand Flash 默认分区的宏,如下:

#define CONFIG_MTD_NAND_YAFFS2   1 // 定义一个管理对Yaffs2 支持的宏

// 开启Nand Flash 默认分区,注意此处的分区要和你的内核中的分区保持一致 
#define MTDIDS_DEFAULT "nand0=nandflash0" 
#define MTDPARTS_DEFAULT "mtdparts=nandflash0:192k(bootloader)," /
                     "64k(params)," /
                     "2m(kernel)," /
                     "-(root)"

 

②、在common/cmd_nand.c  原来对Nand 操作的命令集列表中添加Yaffs2 Nand 的写命令,如下:// U_BOOT_CMD 中添加

U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,
    "NAND sub-system",
    "info - show available NAND devices/n"
    "nand device [dev] - show or set current device/n"
    "nand read - addr off|partition size/n"
    "nand write - addr off|partition size/n"
    " read/write 'size' bytes starting at offset 'off'/n"
    " to/from memory address 'addr', skipping bad blocks./n"

// 注意:这里只添加了yaffs2 的写命令,因为我们只用u-boot 下载( 即写) 功能,所以我们没有添加yaffs2 读的命令
#if defined(CONFIG_MTD_NAND_YAFFS2)
    "nand write[.yaffs2] - addr off|partition size - write `size' byte yaffs image/n"
    " starting at offset off' from memory address addr' (.yaffs2 for 512+16 NAND)/n"
#endif


    "nand erase [clean] [off size] - erase 'size' bytes from/n"
    " offset 'off' (entire device if not specified)/n"
    "nand bad - show bad blocks/n"
    "nand dump[.oob] off - dump page/n"
    "nand scrub - really clean NAND erasing bad blocks (UNSAFE)/n"
    "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)/n"
    "nand biterr off - make a bit error at offset (UNSAFE)"
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
    "/n"
    "nand lock [tight] [status]/n"
    " bring nand to lock state or display locked pages/n"
    "nand unlock [offset] [size] - unlock section"
#endif
);

接着,在该文件中对nand 操作的do_nand 函数中添加yaffs2 nand 的操作,如下:

if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) 
    {
        int read;

        if (argc < 4)
            goto usage;

        addr = (ulong)simple_strtoul(argv[2], NULL, 16);

        read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
        printf("/nNAND %s: ", read ? "read" : "write");
        if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
            return 1;

        s = strchr(cmd, '.');
        if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) 
        {
            if (read)
                ret = nand_read_skip_bad(nand, off, &size, (u_char *)addr);
            else
                ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr);
        }

// 添加yaffs2 相关操作,注意该处又关联到nand_write_skip_bad 函数

#if defined(CONFIG_MTD_NAND_YAFFS2)
        else if (s != NULL && (!strcmp(s, ".yaffs2")))
        {
            nand->rw_oob = 1;
            nand->skipfirstblk = 1;
            ret = nand_write_skip_bad(nand,off,&size,(u_char *)addr);
            nand->skipfirstblk = 0;
            nand->rw_oob = 0;
        }
#endif

        else if (!strcmp(s, ".oob")) 
        {
            /* out-of-band data */
            mtd_oob_ops_t ops = 
            {
                .oobbuf = (u8 *)addr,
                .ooblen = size,
                .mode = MTD_OOB_RAW
            };

            if (read)
                ret = nand->read_oob(nand, off, &ops);
            else
                ret = nand->write_oob(nand, off, &ops);
        } 
        else 
        {
            printf("Unknown nand command suffix '%s'./n", s);
            return 1;
        }

        printf(" %zu bytes %s: %s/n", size, read ? "read" : "written", ret ? "ERROR" : "OK");

        return ret == 0 ? 0 : 1;
    }

③、include/linux/mtd/mtd.h 头文件的mtd_info 结构体中添加上面用到rw_oob skipfirstblk 数据成员,如下:

#if defined(CONFIG_MTD_NAND_YAFFS2) 
    u_char rw_oob; 
    u_char skipfirstblk; 
#endif

 

④、 在第二步关联的 drivers/mtd/nand/nand_util.c  nand_write_skip_bad 函数中添加对Nand OOB 的相关操作,如下:

int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer)
{
    int rval;
    size_t left_to_write = *length;
    size_t len_incl_bad;
    u_char *p_buffer = buffer;

#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support
    if(nand->rw_oob==1)    
    {
        size_t oobsize = nand->oobsize;
        size_t datasize = nand->writesize;
        int datapages = 0;

        if (((*length)%(nand->oobsize+nand->writesize)) != 0) 
        {
         printf ("Attempt to write error length data!/n");
         return -EINVAL;
     }

        datapages = *length/(datasize+oobsize);
        *length = datapages*datasize;
        left_to_write = *length;
    }
#endif

    /* Reject writes, which are not page aligned */
    if ((offset & (nand->writesize - 1)) != 0 ||
     (*length & (nand->writesize - 1)) != 0) {
        printf ("Attempt to write non page aligned data/n");
        return -EINVAL;
    }

    len_incl_bad = get_len_incl_bad (nand, offset, *length);

    if ((offset + len_incl_bad) >= nand->size) {
        printf ("Attempt to write outside the flash area/n");
        return -EINVAL;
    }

#if !defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support 
    if (len_incl_bad == *length) {
        rval = nand_write (nand, offset, length, buffer);
        if (rval != 0)
            printf ("NAND write to offset %llx failed %d/n",
                offset, rval);

        return rval;
    }
#endif

    while (left_to_write > 0) {
        size_t block_offset = offset & (nand->erasesize - 1);
        size_t write_size;

        WATCHDOG_RESET ();

        if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
            printf ("Skip bad block 0x%08llx/n",
                offset & ~(nand->erasesize - 1));
            offset += nand->erasesize - block_offset;
            continue;
        }

#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support 
        if(nand->skipfirstblk==1)    
        {
            nand->skipfirstblk=0;
            printf ("Skip the first good block %llx/n", offset & ~(nand->erasesize - 1));
            offset += nand->erasesize - block_offset;
            continue;
        }
#endif

        if (left_to_write < (nand->erasesize - block_offset))
            write_size = left_to_write;
        else
            write_size = nand->erasesize - block_offset;

        printf("/rWriting at 0x%llx -- ",offset); //add yaffs2 file system support


        rval = nand_write (nand, offset, &write_size, p_buffer);
        if (rval != 0) {
            printf ("NAND write to offset %llx failed %d/n",
                offset, rval);
            *length -= left_to_write;
            return rval;
        }

        left_to_write -= write_size;
        printf("%d%% is complete.",100-(left_to_write/(*length/100)));
        offset += write_size;

#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support 
        if(nand->rw_oob==1)    
        {
            p_buffer += write_size+(write_size/nand->writesize*nand->oobsize);
        } 
        else    
        {
            p_buffer += write_size;
        }
#else
        p_buffer += write_size;
#endif

    }

    return 0;
}

⑤、在第四步nand_write_skip_bad 函数中我们看到又对nand_write 函数进行了访问,所以这一步是到 drivers/mtd/nand/nand_base.c  nand_write 函数中添加对yaffs2 的支持,如下:

static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf) 
{ 
    struct nand_chip *chip = mtd->priv; 
    int ret;

 

#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support

    int oldopsmode = 0;

    if(mtd->rw_oob==1)    
    { 
        int i = 0; 
        int datapages = 0;

        size_t oobsize = mtd->oobsize; 
        size_t datasize = mtd->writesize;

        uint8_t oobtemp[oobsize]; 
        datapages = len / (datasize);

        for(i = 0; i < (datapages); i++)    
        { 
            memcpy((void *)oobtemp, (void *)(buf + datasize * (i + 1)), oobsize); 
            memmove((void *)(buf + datasize * (i + 1)), (void *)(buf + datasize * (i + 1) + oobsize), (datapages - (i + 1)) * (datasize) + (datapages - 1) * oobsize); 
            memcpy((void *)(buf+(datapages) * (datasize + oobsize) - oobsize), (void *)(oobtemp), oobsize); 
        } 
    } 
#endif

 

    /* Do not allow reads past end of device */ 
    if ((to + len) > mtd->size) 
        return -EINVAL; 
    if (!len) 
        return 0;

    nand_get_device(chip, mtd, FL_WRITING);

    chip->ops.len = len; 
    chip->ops.datbuf = (uint8_t *)buf;

 

#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support

    if(mtd->rw_oob!=1)    
    { 
        chip->ops.oobbuf = NULL; 
    } 
    else    
    { 
        chip->ops.oobbuf = (uint8_t *)(buf + len); 
        chip->ops.ooblen = mtd->oobsize; 
        oldopsmode = chip->ops.mode; 
        chip->ops.mode = MTD_OOB_RAW; 
    } 
#else 
    chip->ops.oobbuf = NULL; 
#endif

 

    ret = nand_do_write_ops(mtd, to, &chip->ops);

    *retlen = chip->ops.retlen;

    nand_release_device(mtd);

 

#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support

    chip->ops.mode = oldopsmode; 
#endif

 

    return ret; 
}

OK ,对yaffs2 支持的代码已修改完毕,重新编译u-boot 并下载到nand 中,启动开发板,在u-boot 的命令行输入:nand help查看nand 的命令,可以看到多了一个nand write[.yaffs2] 的命令,这个就是用来下载yaffs2 文件系统到nand 中的命令了。

⑥、 使用nand write[.yaffs2] 命令把事前制作好的yaffs2 文件系统下载到Nand Flash (yaffs2 文件系统的制作请参考后文) ,下载操作步骤和效果图如下:

tftp 0x30000000 root.bin //  tftp  yaffs2 文件系统下载到内存的 0x30000000 位置 

nand erase 0x250000 0x3db0000 // 擦除 Nand 的文件系统分区 

nand write.yaffs2 0x30000000 0x250000 0x658170 // 将内存中的 yaffs2 文件系统写入 Nand 的文件系统分区,注意这里的 0x658170  yaffs2 文件系统的实际大小 ( 可以在 tftp 传送完后可以看到 ) ,要写正确,否则会形成假坏块

 

2  Linux2.6.37 下移植 yaffs 文件系统

原始的linux 内核是不支持Yaffs2 文件系统的,我们首先需要下载yaffs2 的内核补丁,给内核打上yaff2 补丁才能使内核支持该文件系统。

yaffs2 老版本不支持2.6.36 以上内核。  网上下载的yaffs2 常见版本(点击http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/ 下方的Download GNU tarball 进行下载)一般不支持2.6.36/37 。但2.6.36 一下版本依然可以使用。

最新的yaffs2 采用git 发布,利用git 工具下载到最新的yaffs2 源代码,即可支持。办法是使用到www.yaffs.net 发布的git方法获得最新版,并且查看readme 确认其支持2.6.36/37 yaffs 有一个较大的变化,是在2.6.36/37 内核发布之后的一段时间里出现的,主要就是patch-ker.sh 多了一个参数,m/s 是选择multi version 支持,还是single version 支持。(注意:在最新的linux 版本下用multi version 支持。)

(1) 下载源代码

如果系统已经安装git 工具,就直接执行:

git clone git://www.aleph1.co.uk/yaffs2

如果没有git 工具,请首先下载安装git http://git-scm.com/ )。当然,也可以在windows 下用git 工具下载。

  (2) 给内核打补丁

yaffs 源代码下载完后,放到某个目录下(但不要放在内核目录下!)进入yaffs 源代码目录:

#cd yaffs2

打补丁(注意参数顺序不能错):

#./patch-kernel.sh c m   ../linux-2.6.37.1

(3) 然后配置内核:

#cd    ../linux-2.6.37.1   // 返回内核根目录

# make ARCH arm CROSS_COMPILE=arm-linux-  menuconfig

File systems -->

Miscellaneous filesystems -->

<*> YAFFS2 file system support

(4) 重新编译内核

# make ARCH arm CROSS_COMPILE=arm-linux-

然后制作新的uImage ,加载或者烧写到FLASH ,如果能正确引导并加载yaffs 文件系统则移植成功。

特别说明:一旦在使用新版本yaffs 补丁之前使用过旧版本补丁,新版本的补丁则打不上了,建议使用新版本重新编译内核。

=======================

需要注意:因为windows 中下载导致文件编码和linux 的不同。所以,如果是在windows 下用git 下载并传递到linux 下的,则需要修改两个文件的编码:

  (1) linux 下,进入yaffs2 源代码目录

#vi patch-kernel.sh

然后在vi 中执行如下命令:

 :set ff=unix

保存退出

然后修改权限使patch-kernel.sh 具有可执行权限:

#chmod  755  patch-kernel.sh

  (3) 修改fs/yaffs2/Kconfig 的编码

#vi  fs/yaffs2/Kconfig

vi 中执行命令:

:set  ff=unix

保存退出, 按照上述步骤进行打补丁。

2 、用 busybox 制作 yaffs2 根文件系统

所谓的根文件系统,就是创建各个目录,并且在里面创建各种文件,比如在/bin,/sbin/ 目录下存放各种可执行的程序,在/etc 目录下存放配置文件,在/lib 目录下存放库文件,下面就可以文件系统的移植。

1 、根文件系统的目录结构 
bin 
存放所有用户都可以使用的、基本的命令。
sbin 
存放的是基本的系统命令,它们用于启动系统、修复系统等。
usr 
里面存放的是共享、只读的程序和数据。
proc 
这是个空目录,常作为proc 文件系统的挂载点。
dev 
该目录存放设备文件和其它特殊文件。
etc 
存放系统配置文件,包括启动文件。
lib 
存放共享库和可加载块( 即驱动程序) ,共享库用于启动系统、运行根文件系统中的可执行程序。
boot 
引导加载程序使用的静态文件
home 
用户主目录,包括供服务账号锁使用的主目录,如FTP
mnt 
用于临时挂接某个文件系统的挂接点,通常是空目录。也可以在里面创建空的子目录。
opt 
给主机额外安装软件所摆放的目录。
root root
 用户的主目录
tmp 
存放临时文件,通常是空目录。
var 
存放可变的数据。

 

2 、建立根文件系统的目录

进入工作目录, 创建一个shell 的脚本用于构建根文件系统的各个目录。mkrootfs.sh ,平且改变执行的权限。

sudo chmod 777 mkrootfs.sh

脚本内容如下:

#!/ bin / sh 
echo 
"------Create rootfs directons start...--------" 
mkdir rootfs 
cd rootfs 
echo 
"--------Create root,dev....----------" 
mkdir root dev etc boot tmp var sys proc lib mnt home 
mkdir etc 
/ init . d etc / rc . d etc / sysconfig 
mkdir usr 
/ sbin usr / bin usr / lib usr / modules

mkidr proc / sys mkidr proc / sys / kernel

mkidr proc / sys / kernel /

echo "make node in dev/console dev/null" 
mknod 
- m 600 dev / console c 5 1 
mknod 
- m 600 dev / null c 1 3 
mkdir mnt 
/ etc mnt / jffs2 mnt / yaffs mnt / data mnt / temp 
mkdir var 
/ lib var / lock var / run var / tmp 
chmod 1777 tmp 
chmod 1777 var 
/ tmp 
echo 
"-------make direction done---------"

 

改变了tmp 目录的使用权,让它开启sticky 位,为tmp 目录的使用权开启此位,可确保tmp 目录底下建立的文件,,只有建立它的用户有权删除。

3 、编译和安装Busybox

Bosybox 是一个遵循 GPL v2 协议的开源项目,它在编写过程总对文件大小进行优化,并考虑了系统资源有限( 比如内存等)的情况,使用 Busybox 可以自动生成根文件系统所需的bin sbin usr 目录和 linuxrc 文件。 

首先下载busybox ,下载地址:www.busybox.net

下载链接:http://www.busybox.net/downloads/busybox-1.18.3.tar.bz2

解压源代码:

#tar -jxvf  busybox-1.18.3.tar.bz2

修改Makefile 中的交叉链和系统架构:

CROSS_COMPILE ?=arm-linux-

ARCH ?=arm

配置编译选项:

如果修改了Makefile 则使用如下命令

#make  menuconfig

如果未修改Makefile 则使用如下命令:

# make ARCH arm CROSS_COMPILE=arm-linux- menuconfig

  [A] 指定安装位置:

Busybox Settings  --->

Installation Options ("make install" behavior)  --->

BusyBox installation prefix-->

输入:../rootfs // 实际中,要根据计划的文件系统根设定!

[B] 指定mdev 动态文件系统

Linux System Utilities --->

[*]Support /etc/mdev.conf

[*]Support command execution at device addition/removal

说明:在busybox 中配置对dev 下设备类型的支持dev 的创建有三种方法: 
1 )手动创建:在制作根文件系统的时候,就在 dev 目录下创建好要使用的设备文件,系统
挂接根文件系统后,就可以使用 dev 目录下的设备文件了。  
2 )使用 devfs 文件系统:这种方法已经过时,具有不确定的设备映射、没有足够的主/ 次设备号、devfs 消耗大量的内存。  
3 udev : 它是个用户程序,(u 是指user space ,dev 是指device )能根据系统中硬件设备的状态动态的更新设备文件,包括设备文件的创建、删除等。使用udev 机制也不需要/dev 目录下创建设备节点, 它需要一些用户程序的支持,并且内核要支持sysfs 文件系统。它的操作相对复杂,但灵活性很高  mdev  busybox 自带的一个简化版的 udev ,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序所需的节点文件。在以busybox 为基础构建嵌入式linux 的根文件系统时,使用它是最优的选择。配置时需要增加对 mdev 的支持。 

 

4 、编译busybox  
  # make ARCH arm CROSS_COMPILE=arm-linux-   install  
 rootfs 目录下会生成目录 bin sbin usr 和文件 linuxrc 的内容。 
5 、 建立etc 目录 
 init 进程根据/etc/inittab 文件来创建其他的子进程,比如调用脚本文件配置IP 地址,挂载其他的文件系统,最后启动shell 等。 
1 )、拷贝主机 etc 目录下的passwd group shadow 文件到 rootfs/etc 目录下。 
2  etc/sysconfig 目录下新建文件HOSTNAME ,内容为”frank ” 。  
3  etc/inittab 文件:  
  仿照Busybox examples/inittab 文件,在etc/ 目录下创建一个inittab 文件.

 

# etc / inittab

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

::respawn:-/bin/sh

::askfirst:-/bin/sh

::ctrlaltdel:/bin/umount -a –r

 

6 、创建etc/init.d/rcS 文件: 
这是一个脚本文件,可以在里面添加自动执行的命令,

#!/ bin / sh 
PATH =/ sbin :/ bin :/ usr / sbin :/ usr / bin 
runlevel = S      // 运行的级别 
prevlevel = N 
umask 022   // 文件夹的掩码 
export PATH runlevel prevlevel 
mount - a     // 挂载/etc/fstab/ 文件指定的所有的文件系统 
echo / sbin / mdev >/ proc / sys / kernel / hotplug 
mdev - s 
/ bin / hostname - F / etc / sysconfig / HOSTNAME // 主机的名字

最后,还要改变它的属性,使它能够运行“

sudo chmod 777 etc / init . d / rcS

7 、创建etc/fstab 文件: 
  
内容如下,表示执行完,“mount -a” 命令后将挂载proc,tmpfs 等包含在该文件中的所有的文件系统。

# device mount - point type option dump fsck order 
proc / proc proc defaults 0 0 
tmpfs / tmp tmpfs defaults 0 0 
none / tmp ramfs defaults 0 0 
sysfs / sys sysfs defaults 0 0 
mdev / dev ramfs defaults 0 0

/etc/fstab/ 文件被用来定义文件系统的 静态信息 ,这些信息被用来控制mount 命令的行为,各个字段的含义以如下:
device: 
要挂载的设备
   
比如/dev/hda2 /dev/mtdblock1 等设备文件,也可以是其他格式的,比如对于proc 文件系统这个字段就没有意义,可以就任意的值,对于NFS 文件系统,这个字段是,<host>:<dir>.
mount-point: 
挂载点
type 
文件系统类型:
   
比如 proc,jffs2,yaffs,ext2 ,nfs 等,也可以是auto ,表示自动检测文件系统类型
options: 
挂接参数,以逗号隔开
/etc /fstab
 的作用不仅仅是用来控制'mount -a' 的行为,即使是一般的mount 命令,也受它的控制,常用的取值还有 auto noauto user 只允许普通用户挂载设备 nouser exec 允许运行所挂载设备上的程序 noexec Ro 只读方式 rw 以读写的方式 sync 修改文件是,它会同步写入设备中 async 不同步
  defaults rw suid dev exec auto nouser async 
等的组合。
  dump 
fsck order: 用来控制dump fsck 程序的行为
dump
 是一个用来备份的文件的程序,fsck 是一个用来检查磁盘的程序,
8   创建etc/profile 文件:

# Ash profile 
# vim : syntax = sh 
# No core file by defaults 
# ulimit - S - c 0 >/ dev / null 2 >& 1 
USER = "id -un" 
LOGNAME =$ USER 
PS1 = '[/u@/h=W]#' 
PATH =$ PATH 
HOSTNAME = '/bin/hostname' 
export USER LOGNAME PS1 PATH

9   制作根文件系统映像文件

我的目标板NandFlash 64MB 的,所以要使用mkyaffs2image 64M 版本这个可执行的文件生成映像文件。使用命令mkyaffs2image rootfs ro otfs.img 生成根文件系统映像文件。把生成的rootsfs.img 文件烧写到nandFlash 中的根文件系统区。重新引导操作系统即可实现文件系统的正确挂载。

 

 

【以下是依据自己实践经历添加的步骤】

10   为自制的文件系统添加库文件

我在做文件系统移植的时候,到上一步后就去烧写了,然后发现开发板出现  出现“Failed_to_execute_/linuxrc   问题,结果到官网找很多资料才知道原来需要把C的库拷贝到文件系统中,因为busybox里的程序很多功能都需要动态链接库,因此如果找不到库,就会报这个错。解决办法是拷贝交叉编译器当中的lib库到rootfs/lib下,usr/lib这个目录我目前没有用,在编译busybox的时候我选择了一项编译配置,就是不使用usr/lib这个目录。我使用的是4.3.2版本的arm-linux-gcc,但是找到交叉编译器目录,发现里面有很多/lib的目录,结果我就随意选择了一个比较像的,然后烧写到板子中,结果板子报错  出现“ Kernel panic - not syncing: Attempted to kill init! ”错误。  然后到网上找了很多类似错误的解决办法,都没有奏效。以至于这个问题困扰了我很久。最后,我发现原来是我考错了交叉编译器/lib的目录,里面有两个目录,目录里面内容几乎一模一样,但是,就是其中的一个才能正常运行。这个库的路径上明确标出的是armv4t,而另一个没有,结果带armv4t的那个lib库就可以正常运行。我的板子是s3c2440的,本身应该就是armv4t的,可是没想到就这个问题,就把我难坏了。修改了这个问题以后,我的板子正常加载和启动了,然后到达命令行。






###### 移植过程中遇到的问题及处理:

如果出现“ Kernel panic - not syncing: Attempted to kill init! ”错误,请在编译内核时选择EABI 支持。

Kernel Features  --->

[*] Use the ARM EABI to compile the kernel                 

[*]   Allow old ABI binaries to run with this kernel (EXPERIMENTA)

把这个选上重新编译就可以了,如果文件系统镜像也是新做的则也要考虑文件系统本身有问题的可能性。此外请注意 mkyaffs2image  工具是否正确,我使用友善之臂的工具就出现此错误,但是使用天嵌提供的工具则可以正常使用。

如果出现“Failed_to_execute_/linuxrc  可以根据下面的建议逐个检查。
1. bin/busybox
 文件是可以执行的。
2. 
在配置busybox 的时候要选中shell 选项中的一个选项
3. linuxrc 
是可执行的。
4. 
制作文件系统的时候利用的工具也要留意区分:
    mkcramfs          
制作cramfs 镜像的工具
    mkimage          
 制作jffs2 镜像的工具
    mkyaffs2image      
 制作2.6 yaffs2 的镜像工具(针对Nand Flash 128MB 1GB 的)
    mkyaffsimage       
 制作2.6.13 yaffs2 的镜像工具
    mkyaffsimage_2       
制作2.6.25.8 2.6.30.4 或更高版本内核的yaffs2 的镜像工具(针对Nand Flash   64MB 的)

5 、配置内核时是否取消ECC (我遇到此问题是通过取消ECC 解决此问题。)

NAND Flash support for Samsung S3C SoCs

   Samsung S3C NAND Hardware ECC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值