Chinaunix首页 | 论坛 | 博客
  • 博客访问: 809253
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2016-12-14 21:18:34

转载标明出处:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&id=5756740&uid=22072065
============================================================

1. 移植内核第一课:分析由uboot启动内核的流程,根据机器ID配置内核

机器ID:
    在uboot引导程序中,最后跳转到linux内核,传递给内核的参数有:机器ID,传递给内核参数的地址
    u-boot-2012.04.01中实现:
        static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
            do_bootm_linux(0, argc, argv, &images);
                boot_jump_linux(images);
                    unsigned long machid = gd->bd->bi_arch_number;          // 获取默认的机器ID
                    void (*kernel_entry)(int zero, int arch, uint params);  // 构造函数
                    kernel_entry = (void (*)(int, int, uint))images->ep;   
                    s = getenv("machid");          // 从环境参数获取机器ID
                    r2 = gd->bd->bi_boot_params;   // 获取BootLoader传递参数给kernel的地址
                    kernel_entry(0, machid, r2);   // 启动内核
    如果在uboot代码中,默认设置了机器ID,就用这个机器ID;
    而如果在环境参数中,设置了这个参数,就用环境变量定义的。
    
    在uboot的u-boot-2012.04.01\arch\arm\include\asm\mach-types.h 文件中可以看到单板的机器ID:
    #define MACH_TYPE_SMDK2410             193    // 0xc1
    #define MACH_TYPE_MINI2440             1999   // 0x7cf
    #define MACH_TYPE_S3C2440              362    // 0x16a
    
    这些机器ID与在内核代码中定义的机器ID是一致的。
    u-boot-2012.04.01设置的默认的机器ID为: MACH_TYPE_SMDK2410 = 193
    第二阶段启动代码:
        void board_init_r(gd_t *id, ulong dest_addr)
            board_init();  
                gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;    /* 设置的默认机器ID     */
                gd->bd->bi_boot_params = 0x30000100;            /* 设置的启动参数的地址 */
                
可以在uboot启动参数中设置机器ID:
    set machid 0xc1    // 193  MACH_TYPE_SMDK2410     在uboot中默认的机器ID
    set machid 0x7cf   // 1999 MACH_TYPE_MINI2440     在环境参数中设置启动,修改波特率为115200,可以看到打印的数据
    set machid 16a     // SMDK2440  mach-smdk2440.c   在环境参数中设置启动,修改波特率为115200,打印的数据为乱码
注意:
    这里我们要移植的板子对应应该是: SMDK2440。因为在移植uboot的时候,最后传递给内核的机器ID默认为:MACH_TYPE_SMDK2410,
    这个是不对的,我们可以在uboot启动的时候,手动设置机器ID的环境变量,并存储在NAND的环境参数中,以后内核每次启动都是检测
    机器ID:SMDK2440 = 0x16a。

    
比较 MACH_TYPE_MINI2440 和 MACH_TYPE_S3C2440 在源码中的不同,肯定是时钟初始化不对:
我们要移植的是SMDK2440的开发板,所以我们看MACH_TYPE_S3C2440的初始化时钟的函数:
linux-3.4.2\arch\arm\mach-s3c24xx\Mach-smdk2440.c
    MACHINE_START(S3C2440, "SMDK2440")
        /* Maintainer: Ben Dooks */
        .atag_offset    = 0x100,

        .init_irq    = s3c24xx_init_irq,
        .map_io        = smdk2440_map_io,
        .init_machine    = smdk2440_machine_init,
        .timer        = &s3c24xx_timer,
        .restart    = s3c244x_restart,
    MACHINE_END

    初始化函数:
        smdk2440_map_io
            s3c24xx_init_clocks(16934400);  // 这里默认的时钟频率为16934400,肯定是不对的,应该是12MHZ。
            改为:
            s3c24xx_init_clocks(12000000);
           
===============================================

2. 移植新内核第二课: 修改分区, 制作新的文件系统

2.1 分区表设置:arch/arm/mach-s3c24xx/common-smdk.c
    static struct mtd_partition smdk_default_nand_part[] = {
        [0] = {
            .name    = "Boot Agent",
            .size    = SZ_16K,
            .offset    = 0,
        },
        [1] = {
            .name    = "S3C2410 flash partition 1",
            .offset = 0,
            .size    = SZ_2M,
        },
        [2] = {
            .name    = "S3C2410 flash partition 2",
            .offset = SZ_4M,
            .size    = SZ_4M,
        },
        [3] = {
            .name    = "S3C2410 flash partition 3",
            .offset    = SZ_8M,
            .size    = SZ_2M,
        },
        [4] = {
            .name    = "S3C2410 flash partition 4",
            .offset = SZ_1M * 10,
            .size    = SZ_4M,
        },
        [5] = {
            .name    = "S3C2410 flash partition 5",
            .offset    = SZ_1M * 14,
            .size    = SZ_1M * 10,
        },
        [6] = {
            .name    = "S3C2410 flash partition 6",
            .offset    = SZ_1M * 24,
            .size    = SZ_1M * 24,
        },
        [7] = {
            .name    = "S3C2410 flash partition 7",
            .offset = SZ_1M * 48,
            .size    = MTDPART_SIZ_FULL,
        }
    };
    
    修改为:
    static struct mtd_partition smdk_default_nand_part[] = {
        [0] = {
            .name    = "u-boot",
            .size    = SZ_256K,
            .offset    = 0,
        },
        [1] = {
            .name    = "params",
            .offset = MTDPART_OFS_APPEND,  // 表示是追加信息
            .size    = SZ_128K,
        },
        [2] = {
            .name    = "kernel",
            .offset = MTDPART_OFS_APPEND,
            .size    = SZ_2M,
        },
        [3] = {
            .name    = "rootfs",
            .offset    = MTDPART_OFS_APPEND,
            .size    = MTDPART_SIZ_FULL, // 表示剩余的大小都为rootfs
        }
    };
    
mtd分区信息:
device nand0 , # parts = 4
 #: name                size            offset          mask_flags
 0: u-boot              0x00040000      0x00000000      0
 1: params              0x00020000      0x00040000      0
 2: kernel              0x00200000      0x00060000      0
 3: rootfs              0x0fda0000      0x00260000      0

active partition: nand0,0 - (u-boot) 0x00040000 @ 0x00000000

defaults:
mtdids  : nand0=jz2440-0
mtdparts: mtdparts=jz2440-0:256k(u-boot),128k(params),2m(kernel),-(rootfs)    

启动发现分区不对啊,需要重新修改:这里有注意对比啊。
Creating 4 MTD partitions on "NAND":
0x000000000000-0x000000040000 : "u-boot"
0x000000040000-0x000000080000 : "params"   // 这里有问题,这里错误直接导致后面也有问题
0x000000080000-0x000000280000 : "kernel"
0x000000280000-0x000010000000 : "rootfs"

2.2 烧写YAFFS文件系统测试
tftp 30000000 fs_mini_mdev.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000 $filesize

启动参数设置:
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3; save

可以挂接yaffs2文件系统,但是没法启动init进程。

2.3 烧写jffs2文件系统测试
tftp 30000000 fs_mini_mdev.jffs2; nand erase.part rootfs; nand write.jffs2 30000000 260000 $filesize

设置启动参数:
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2; save

可以挂接jffs2文件系统,且能进入shell程序界面。

2.4 利用busybox制作根文件系统

2.4.1 下载busybox:busybox-1.20.0.tar.bz2
2.4.2 解压busybox,安装交叉编译器

    解压:tar xjf busybox-1.20.0.tar.bz2
    安装交叉编译器,修改主目录下的Makefile文件:
    164 CROSS_COMPILE ?=
    改为
    164 CROSS_COMPILE ?= arm-linux-
    
    配置:make menuconfig
    CROSS_COMPILER_PREFIX 设置为:arm-linux-

2.4.3 编译:make

2.4.4 创建根文件系统的文件夹:/work/nfs_root/my_fs
    mkdir my_fs
    
2.4.5 安装busybox到刚建立的根文件目录中
    book@book-desktop:/work/system/busybox-1.20.0$ make install CONFIG_PREFIX=/work/nfs_root/my_fs
    编译安装完成,可以查看目录:/work/nfs_root/my_fs 已经有以下目录,表示安装成功。
    bin  linuxrc  sbin  usr

2.4.6 安装库文件lib
    book@book-desktop:/work/nfs_root/my_fs$ mkdir lib
    book@book-desktop:/work/nfs_root/my_fs$ mkdir usr/lib -p     // -p 表示递归创建文件夹
    
    从编译器里面拷贝库文件到文件系统目录中:
    cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so* /work/nfs_root/my_fs/lib -d
    cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /work/nfs_root/my_fs/usr/lib -d

2.4.7 构建etc文件:
    cp /work/nfs_root/first_fs/etc/   /work/nfs_root/my_fs/ -rf

2.4.8 构建dev文件:
    cd /work/nfs_root/my_fs
    mkdir dev
    book@book-desktop:/work/nfs_root/my_fs/dev$ sudo mknod console c 5 1
    book@book-desktop:/work/nfs_root/my_fs/dev$ sudo mknod null c 1 3
    book@book-desktop:/work/nfs_root/my_fs/dev$ ls -l
    total 0
    crw-r--r-- 1 root root 5, 1 2016-05-23 14:28 console
    crw-r--r-- 1 root root 1, 3 2016-05-23 14:28 null

2.4.9 构建其他目录:proc tmp mnt sys root
    book@book-desktop:/work/nfs_root/my_fs$ mkdir proc tmp mnt sys root
    book@book-desktop:/work/nfs_root/my_fs$ ls
    bin  dev  etc  lib  linuxrc  mnt  proc  root  sbin  sys  tmp  usr

2.5 制作jffs2:
    mkfs.jffs2 -n -s 2048 -e 128KiB -d my_fs -o my_fs.jffs2


2.6 测试
    烧写my_fs.jffs2到板子
    tftp 30000000 my_fs.jffs2; nand erase.part rootfs; nand write.jffs2 30000000 260000 $filesize

    挂接jffs2文件系统,修改启动参数:
    set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2

    利用新内核启动,jffs2文件系统
    tftp 32000000 uImage; bootm 32000000

    启动打印错误信息:
    ....
    drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
    ALSA device list:
      No soundcards found.
    VFS: Mounted root (jffs2 filesystem) on device 31:3.
    Freeing init memory: 172K
    Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
    ......


2.7 内核编译增加EABI接口
arm-linux-gcc是使用EABI接口,所以内核也需要支持这种接口。
| Symbol: AEABI [=y]                                                                    |  
| Type  : boolean                                                                       |  
| Prompt: Use the ARM EABI to compile the kernel                                        |  
|   Defined at arch/arm/Kconfig:1678                                                    |  
|   Location:                                                                           |  
|     -> Kernel Features                                                                |  
|   Selected by: ARCH_OMAP2PLUS_TYPICAL [=n] && ARCH_OMAP2PLUS [=n] || THUMB2_KERNEL [=

重新编译内核,生成新的内核镜像文件: uImage_eabi
$make uImage

挂接jffs2文件系统,修改启动参数:
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2

利用新内核启动,jffs2文件系统
tftp 32000000 uImage_eabi; bootm 32000000

测试,下载新的内核到板子,挂接jffs2文件系统,启动打印信息:
    ......
    ALSA device list:
      No soundcards found.
    VFS: Mounted root (jffs2 filesystem) on device 31:3.
    Freeing init memory: 164K
    ifconfig: SIOCSIFADDR: No such device
    can't open /dev/s3c2410_serial0: No such file or directory
    can't open /dev/s3c2410_serial0: No such file or directory
    can't open /dev/s3c2410_serial0: No such file or directory
    can't open /dev/s3c2410_serial0: No such file or directory
    can't open /dev/s3c2410_serial0: No such file or directory
    can't open /dev/s3c2410_serial0: No such file or directory
    ....


问题1:    
    打印语句:ifconfig: SIOCSIFADDR: No such device
回答1:
    是因为文件系统的配置文件:etc/init.d/rcS
    #!/bin/sh
    ifconfig eth0 192.168.1.17   // 目前还没有配置DM9000网卡,所以当运行这句脚本命令将打印找不到设置的警告

    mount -a
    mkdir /dev/pts
    mount -t devpts devpts /dev/pts
    echo /sbin/mdev > /proc/sys/kernel/hotplug
    mdev -s
    
问题2:
    打印语句:can't open /dev/s3c2410_serial0: No such file or directory
回答2:
    在配置文件:etc/inittab 定义了这句命令:s3c2410_serial0::askfirst:-/bin/sh
    # /etc/inittab
    ::sysinit:/etc/init.d/rcS
    s3c2410_serial0::askfirst:-/bin/sh
    ::ctrlaltdel:/sbin/reboot
    ::shutdown:/bin/umount -a -r

    但是在设备文件中根本没定义这个设备:/dev/s3c2410_serial0
    可以查看设备文件,根本没建立这个设备:
    $ ls dev/ -l
    total 0
    crw-r--r-- 1 root root 5, 1 2016-12-10 09:14 console
    crw-r--r-- 1 root root 1, 3 2016-12-10 09:14 null
    
    所以解决方法有两条:
    方法1:改变这个脚本命令:
        s3c2410_serial0::askfirst:-/bin/sh
        修改为:
        ttySAC0::askfirst:-/bin/sh
    方法2:
        在设备文件/dev目录下,增加一个设备文件s3c2410_serial0:
        sudo mknod s3c2410_serial0 c 204 64

重新制作jffs2:
mkfs.jffs2 -n -s 2048 -e 128KiB -d my_fs -o my_fs.jffs2

重新烧写jffs2文件系统:
tftp 30000000 my_fs.jffs2; nand erase.part rootfs; nand write.jffs2 30000000 260000 $filesize

重新烧写新的内核镜像启动,基本上就OK了,看打印信息:
.....
ALSA device list:
  No soundcards found.
jffs2: Empty flash at 0x003b8fd8 ends at 0x003b9000
VFS: Mounted root (jffs2 filesystem) on device 31:3.
Freeing init memory: 164K

Please press Enter to activate this console.
/ #
/ #
/ #
已经启动shell脚本。

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

3. 移植新内核第三课: 移植YAFFS文件系统

3.1 下载解压yaffs源代码
注意:在linux内核中并没有集成yaffs文件系统的源代码,需要额外去下载。
tar xjf yaffs2.tar.bz2
cd yaffs2/
./patch-ker.sh c m /work/system/linux-3.4.2

3.2 内核树种查看
查看源代码中是否集成了yaffs源码:
cd ../linux-3.4.2/
ls fs/yaffs2/

3.3 配置内核支持yaffs
  | Symbol: YAFFS_DOES_ECC [=n]                                                           |  
  | Type  : boolean                                                                       |  
  | Prompt: Lets yaffs do its own ECC                                                     |  
  |   Defined at fs/yaffs2/Kconfig:51                                                     |  
  |   Depends on: MISC_FILESYSTEMS [=y] && YAFFS_FS [=n] && YAFFS_YAFFS1 [=n] && !YAFFS_9 |  
  |   Location:                                                                           |  
  |     -> File systems                                                                   |  
  |       -> Miscellaneous filesystems (MISC_FILESYSTEMS [=y])                            |  
  |         -> yaffs2 file system support (YAFFS_FS [=n])                                 |  
  |           -> 512 byte / page devices (YAFFS_YAFFS1 [=n])                              |  
  |             -> Use older-style on-NAND data format with pageStatus byte (YAFFS_9BYTE_ |  
  |   
修改为:
  | Symbol: YAFFS_DOES_ECC [=n]                                                           |  
  | Type  : boolean                                                                       |  
  | Prompt: Lets yaffs do its own ECC                                                     |  
  |   Defined at fs/yaffs2/Kconfig:51                                                     |  
  |   Depends on: MISC_FILESYSTEMS [=y] && YAFFS_FS [=y] && YAFFS_YAFFS1 [=y] && !YAFFS_9 |  
  |   Location:                                                                           |  
  |     -> File systems                                                                   |  
  |       -> Miscellaneous filesystems (MISC_FILESYSTEMS [=y])                            |  
  |         -> yaffs2 file system support (YAFFS_FS [=y])                                 |  
  |           -> 512 byte / page devices (YAFFS_YAFFS1 [=y])                              |  
  |             -> Use older-style on-NAND data format with pageStatus byte (YAFFS_9BYTE_ |     

重新编译内核
$ make uImage

打印一堆错误。
...
fs/yaffs2/yaffs_vfs.c:440: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_vfs.c:445: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_vfs.c:447: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_mtd_put_super':
fs/yaffs2/yaffs_vfs.c:2514: error: 'struct mtd_info' has no member named 'sync'
fs/yaffs2/yaffs_vfs.c:2515: error: 'struct mtd_info' has no member named 'sync'

fs/yaffs2/yaffs_vfs.c: In function 'yaffs_internal_read_super':
fs/yaffs2/yaffs_vfs.c:2702: error: 'struct mtd_info' has no member named 'erase'
fs/yaffs2/yaffs_vfs.c:2703: error: 'struct mtd_info' has no member named 'read'
fs/yaffs2/yaffs_vfs.c:2704: error: 'struct mtd_info' has no member named 'write'
fs/yaffs2/yaffs_vfs.c:2705: error: 'struct mtd_info' has no member named 'read_oob'
fs/yaffs2/yaffs_vfs.c:2706: error: 'struct mtd_info' has no member named 'write_oob'
fs/yaffs2/yaffs_vfs.c:2707: error: 'struct mtd_info' has no member named 'block_isbad'
fs/yaffs2/yaffs_vfs.c:2708: error: 'struct mtd_info' has no member named 'block_markbad'
fs/yaffs2/yaffs_vfs.c:2732: error: 'struct mtd_info' has no member named 'erase'
fs/yaffs2/yaffs_vfs.c:2733: error: 'struct mtd_info' has no member named 'block_isbad'
fs/yaffs2/yaffs_vfs.c:2734: error: 'struct mtd_info' has no member named 'block_markbad'
fs/yaffs2/yaffs_vfs.c:2734: error: 'struct mtd_info' has no member named 'read'
fs/yaffs2/yaffs_vfs.c:2734: error: 'struct mtd_info' has no member named 'write'
fs/yaffs2/yaffs_vfs.c:2736: error: 'struct mtd_info' has no member named 'read_oob'
fs/yaffs2/yaffs_vfs.c:2736: error: 'struct mtd_info' has no member named 'write_oob'
fs/yaffs2/yaffs_vfs.c:2757: error: 'struct mtd_info' has no member named 'erase'
fs/yaffs2/yaffs_vfs.c:2757: error: 'struct mtd_info' has no member named 'read'
fs/yaffs2/yaffs_vfs.c:2757: error: 'struct mtd_info' has no member named 'write'
fs/yaffs2/yaffs_vfs.c:2759: error: 'struct mtd_info' has no member named 'read_oob'
fs/yaffs2/yaffs_vfs.c:2759: error: 'struct mtd_info' has no member named 'write_oob'
fs/yaffs2/yaffs_vfs.c:2967: error: implicit declaration of function 'd_alloc_root'
fs/yaffs2/yaffs_vfs.c:2967: warning: assignment makes pointer from integer without a cast
make[2]: *** [fs/yaffs2/yaffs_vfs.o] Error 1
make[1]: *** [fs/yaffs2] Error 2
make: *** [fs] Error 2

修改错误,直到编译没有错误....
fs/yaffs2/yaffs_vfs.c:2967: error: implicit declaration of function 'd_alloc_root'
在源码中查找:"sb->s_root"
Inode.c (fs\cramfs):    sb->s_root = d_make_root(root);
把'd_alloc_root' 修改为 'd_make_root'

主要是这几个文件中的错误:
yaffs_vfs.c
yaffs_mtdif.c
yaffs_mtdif1.c
yaffs_mtdif2.c
一个一个文件解决,直到编译通过。

制作yaffs文件系统:
mkyaffs2image my_fs my_fs.yaffs2
注意:mkyaffs2image这个工具是在移植u-boot的时候生成的。

下载yaffs文件系统:
tftp 30000000 my_fs.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000  $filesize

下载新内核到板子:
tftp 32000000 uImage_yaffs; bootm 32000000

启动板子,打印信息:
    ......
    ALSA device list:
      No soundcards found.
    yaffs: dev is 32505859 name is "mtdblock3" rw
    yaffs: passed flags ""
    VFS: Mounted root (yaffs filesystem) on device 31:3.
    Freeing init memory: 164K
    Kernel panic - not syncing: No init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
    [] (unwind_backtrace+0x0/0xf8) from [] (panic+0x74/0x1c8)
    [] (panic+0x74/0x1c8) from [] (init_post+0xc0/0x138)
    [] (init_post+0xc0/0x138) from [] (kernel_init+0x16c/0x1bc)

    
发现是以前移植的新的uboot以BUG:
发现1.1.6的UBOOT没问题,所以就是我们移植的新UBOOT: u-boot-2012.04.01有BUG:
    drivers\mtd\nand\Nand_util.c

        if (!need_skip && !(flags & WITH_DROP_FFS)) {
    改为
        if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB)) {
重新编译u-boot.
        
更新u-boot到板子的NOR中:
tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000

重新下载yaffs文件系统:
tftp 30000000 my_fs.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000  $filesize

重新下载新内核到板子启动:
tftp 32000000 uImage_yaffs; bootm 32000000


问题:
    一直挂接不上yaffs文件系统,对照WDS老师的,看看哪里出了问题。

测试:
烧写uboot到NAND中:
tftp 30000000 u-boot.bin; nand erase.part u-boot; nand write 30000000 u-boot

烧写uboot到NOR中:
tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000

烧写自己制作的内核, 支持yaffs文件系统:
tftp 30000000 uImage_yaffs; bootm 30000000

这个时候,不能烧写内核到nand中,因为这个时候的内核大小超过我们预设的2M大小,所以可以启动,而不可以固化在NAND中。
tftp 30000000 uImage_yaffs; nand erase.part kernel; nand write 30000000 kernel

烧写自己制作的yaffs文件系统:
tftp 30000000 my_fs.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000  $filesize


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

4. 新内核移植笔记第四课:裁剪内核大小以及制作补丁文件

4.1 根据配置文件.config来配置需要的选项,以此来达到裁剪内核的目的
4.2 注意:
    在内核中对NAND划分的分区中,kernel分区为:2M。
    所以要配置禁止相关的内核编译选项,使之最终编译的内核镜像文件的大小应该不大于分区大小:2M。

烧写内核:
    tftp 30000000 uImage_new; bootm 30000000
    启动信息:
        SMDK2410 # tftp 30000000 uImage_new; bootm 30000000
        ERROR: resetting DM9000 -> not responding
        dm9000 i/o: 0x20000000, id: 0x90000a46
        DM9000: running in 16 bit mode
        MAC: 00:0c:29:2f:4e:70
        could not establish link
        Using dm9000 device
        TFTP from server 192.168.1.100; our IP address is 192.168.1.17
        Filename 'uImage_new'.
        Load address: 0x30000000
        Loading: #################################################################
                 #################################################################
                 ############
        done
        Bytes transferred = 2070136 (1f9678 hex)
        ## Booting kernel from Legacy Image at 30000000 ...
           Image Name:   Linux-3.4.2
           Image Type:   ARM Linux Kernel Image (uncompressed)
           Data Size:    2070072 Bytes = 2 MiB  // 内核镜像文件大小为:1.97M.
           Load Address: 30008000
           Entry Point:  30008000
           Verifying Checksum ... OK
           Loading Kernel Image ... OK
        OK
        ...................
        ALSA device list:
          No soundcards found.
        yaffs: dev is 32505859 name is "mtdblock3" rw
        yaffs: passed flags ""
        VFS: Mounted root (yaffs filesystem) on device 31:3.
        Freeing init memory: 116K
        ifconfig: SIOCSIFADDR: No such device

        Please press Enter to activate this console.
        / #
            
烧写该内核镜像到NAND中:
    tftp 30000000 uImage_yaffs; nand erase.part kernel; nand write 30000000 kernel

烧写文件系统:
    tftp 30000000 my_fs.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000  $filesize

设置启动参数
    set 'nand read 30000000 kernel;bootm 30000000'
    set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
    set machid 16a          // smdk2440  mach-smdk2440.c
    save

4.3 制作内核的补丁文件:

4.3.1 先把配置文件.config拷贝为config_ok   (注意:一定要记得备份这个配置文件.config)
4.3.2 make distclean   // 清除所有配置生成的东西
4.3.3 清除完后,再制作补丁文件

    复制编译后的内核文件为:linux-3.4.2_configured
    mv linux-3.4.2 linux-3.4.2_configured
    
    下载,解压纯净代码树:
    tar xjf linux-3.4.2.tar.bz2
    
    制作补丁:
    diff -urN linux-3.4.2 linux-3.4.2_configured > linux-3.4.2_configured.patch

    可以查看已经生成了补丁文件:
    $ ls linux-3.4.2_configured.patch -l
    -rw-r--r-- 1 book book 523419 2016-06-15 16:26 linux-3.4.2_configured.patch
    
4.4 给纯净的内核打补丁文件

进入纯内核代码树目录下:
    cd linux-3.4.2
    patch -p1 < ../linux-3.4.2_configured.patch
    cp config_ok .config
    make uImage

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

5. 新内核移植笔记第五课:移植DM9000网卡驱动

【第一种情况:移植内核做好的DM9000驱动】
启动内核可以发现:
如果machID = SMDK2440,则并没有支持网卡
而如果使用mini2440,则支持了网卡驱动。

可以通过设置不同的机器ID这个环境变量,来启动板子看结果:
set machid 16a     // SMDK2440  mach-smdk2440.c    
set machid 7CF       // mini2440  mach-mini2440.c

可以对比修改,将mini2440的DM9000网卡驱动移植到SMDK2440的板子上去。(很容易移植)

DM9000设备在内核中,是注册了一个平台设备驱动。搜索driver.name就可以知道在哪里注册了一个DM9000设备。

mini2440开发板注册DM9000设备流程:
static void __init mini2440_init(void)
    platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
        platform_device_register(devs[i]);  // 在这个devs[i]数组中,有DM9000设备:mini2440_device_eth 这一项
        
static struct platform_device mini2440_device_eth = {
    .name        = "dm9000",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(mini2440_dm9k_resource),
    .resource    = mini2440_dm9k_resource,
    .dev        = {
        .platform_data    = &mini2440_dm9k_pdata,
    },
};        

SMDK2440开发板应该仿照mini2440的做法,加入相关的DM9000初始化的代码,在板子初始化的时候,向内核注册DM9000驱动程序。
linux-3.4.2\arch\arm\mach-s3c24xx\mach-smdk2440.c


【第二种情况:使用厂家移植好的驱动程序】
1. 拷贝驱动程序到内核代码树下
cp dm9000.h dm9dev9000c.c /work/system/linux-3.4.2/drivers/net/ethernet/davicom/

2. 修改Makefile,将dm9dev9000c.c编译进内核文件
vi /work/system/linux-3.4.2/drivers/net/ethernet/davicom/Makefile
    #obj-$(CONFIG_DM9000) += dm9000.o
    修改为:
    obj-$(CONFIG_DM9000) += dm9dev9000c.o
    
3. 重新编译内核
    make uImage
    
4. 烧写进板子,重新启动,可以配置网卡了。
    ifconfig eth0 192.168.1.17

    挂接/mnt
    mount -t nfs -o nolock,vers=2 192.168.1.10:/work/nfs_root /mnt

NFS挂接根文件系统:
设置启动参数
    set bootargs console=ttySAC0,115200 root=/dev/nfs nfsroot=192.168.1.10:/work/nfs_root/my_fs ip=192.168.1.17:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off
    save

yaffs文件设置参数: set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
jiffs文件设置参数: set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
    
   
阅读(1016) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~