android驱动学习(1)

linux系统:
            uboot  -----> linux内核 ------> 根文件系统: bin sbin sys dev etc lib等
二,根文件系统的制作
1,根文件系统的结构
    
        内核的启动:
            kernel_init线程:
                -----> prepare_namespace()
                -----> init_post()
                                            /
                                            |
        ---------------------------------------------------------------------------------------------------------------------
        |             |           |                |                         |             |        |           |        |        |        |       |     |
        bin     sbin     etc            lib                       sys       dev   proc    root home usr   mnt tmp opt
       --------------         |               |                        ----------------------
            |        系统配置/脚本  交叉编译器中获取          |
          busybox                                                     虚拟文件系统:在内存中,有系统自动创建里面的文件       

2,根文件系统的:
    1》创建相关目录
          mkdir myrootfs
          cd myrootfs
          mkdir bin sbin lib etc sys dev proc root home opt usr mnt tmp

2》通过busybox生成bin和sbin中的命令

 拷贝解压配置编译busybox
            ① 将busybox拷贝到/home/farsight/s5pv210/filesystem,并解压
                    [email protected]:~/s5pv210/filesystem$ tar -xvf busybox-1.17.3.tar.bz2
            ② 配置交叉编译器
                164 CROSS_COMPILE ?= arm-none-linux-gnueabi-
                190 ARCH ?= arm
            ③ make menuconfig
                     Busybox Settings  --->
                             Build Options  --->
                                [*] Build BusyBox as a static binary (no shared libs)
                             Installation Options  --->
                                [*] Don't use /usr
                                (./_install) BusyBox installation prefix
          ④ 编译,并安装
                make -j2
                make install
          ⑤ 将_install中的内容拷贝到 myrootfs中
                [email protected]:~/s5pv210/filesystem/busybox-1.17.3/_install$ cp -raf * ../../myrootfs/ 拷贝解压配置编译busybox
            ① 将busybox拷贝到/home/farsight/s5pv210/filesystem,并解压
                    [email protected]:~/s5pv210/filesystem$ tar -xvf busybox-1.17.3.tar.bz2
            ② 配置交叉编译器
                164 CROSS_COMPILE ?= arm-none-linux-gnueabi-
                190 ARCH ?= arm
            ③ make menuconfig
                     Busybox Settings  --->
                             Build Options  --->
                                [*] Build BusyBox as a static binary (no shared libs)
                             Installation Options  --->
                                [*] Don't use /usr
                                (./_install) BusyBox installation prefix
          ④ 编译,并安装
                make -j2
                make install
          ⑤ 将_install中的内容拷贝到 myrootfs中
                [email protected]:~/s5pv210/filesystem/busybox-1.17.3/_install$ cp -raf * ../../myrootfs/

3》拷贝交叉编译器中的库到  myrootfs/lib
     1) 拷贝交叉编译器中的库
          [email protected]:/usr/local/arm/toolchain-4.5.1-farsight/arm-none-linux-gnueabi/lib$ cp -raf * /home/farsight/s5pv210/filesystem/myrootfs/lib
     2) 对拷贝过来的lib中的库文件瘦身
          [email protected]:~/s5pv210/filesystem/myrootfs$ du -sh lib
          18M     lib
          
          //因为瘦身过程会修改库文件,必须要有可写权限,所以需要修改权限
          [email protected]:~/s5pv210/filesystem/myrootfs$ chmod a+w lib/*                */
          //瘦身:arm-none-linux-gnueabi-strip
          [email protected]:~/s5pv210/filesystem/myrootfs$ arm-none-linux-gnueabi-strip lib/*                            */
          arm-none-linux-gnueabi-strip:lib/libgcc_s.so: File format not recognized
          arm-none-linux-gnueabi-strip:lib/libgomp.spec: File format not recognized
          arm-none-linux-gnueabi-strip:lib/libstdc++.so.6.0.14-gdb.py: File format not recognized
          [email protected]:~/s5pv210/filesystem/myrootfs$ du -sh lib
          5.2M    lib

 4》编写etc下的相关脚本文件 ---------------------- 参考busybox源码
        1) 在etc中创建inittab:
                [email protected]:~/s5pv210/filesystem/myrootfs/etc$ touch inittab
        2)参考busybox源码 -----  /examples/inittab
            ::sysinit:/etc/init.d/rcS
            ::askfirst:-/bin/sh
            ::ctrlaltdel:/sbin/reboot
            ::shutdown:/sbin/swapoff -a
            ::shutdown:/bin/umount -a -r
            ::restart:/sbin/init

          格式说明:
             <id>:<runlevels>:<action>:<process>
                <action>:  sysinit ---- 系统初始化
                           respawn ---- 重启/复位
                           askfirst---- 启动时第一次询问:Please press Enter to activate this  console.
                           wait -------等待
                           once -------执行一次
                           restart ----每次重启时执行
                           ctrlaltdel--按下组合键时执行
                           shutdown ---关机时执行
        3) 创建 init.d/rcS 并设置权限    echo与后面必须要空格隔离
            #!/bin/sh

            echo "-------myrootfs start----------------------"     
            /bin/mount -a                //挂载/etc/fstab中指定的所有的文件系统
            /sbin/mdev -s                //创建设备节点和系统的相关信息
            echo "-------myrootfs end----------------------"
            
            注意:修改rcS的权限
                [email protected]:~/s5pv210/filesystem/myrootfs/etc/init.d$ chmod a+x rcS
        4) 创建:etc/fstab
        
                myproc            /proc           proc    defaults    0       0
                mysys             /sys            sysfs    defaults    0       0
                mydev             /dev            tmpfs    defaults    0       0
                mytmp             /tmp             tmpfs    defaults    0       0
            以上步骤完成之后,就得到了一个最简单的根文件系统.
    5》补充:
        1) 注释掉:init.d/rcS 中的
            #/bin/mount -a
            重启开发板,发现在 dev/ sys/ proc/中什么都没有
            
            但是,在init.d/rcS添加:
                /bin/mount -t proc  myproc /proc
                /bin/mount -t sysfs  mysys /sys
                /bin/mount -t tmpfs  mydev /dev
                /bin/mount -t tmpfs  mytmp /tmp
            重启开发板,发现在 dev/ sys/ proc/中有相关的文件存在
            
        2)注释掉:init.d/rcS 中的
            #/sbin/mdev -s
              在dev下不会创建内核中需要加载的驱动对应的设备节点
        3) 创建 : etc/profile
            #!/bin/sh
            export HOSTNAME=farsight
            export USER=root
            export HOME=root
            export PS1="[[email protected]$HOSTNAME \W]\# "
            PATH=/bin:/sbin:/usr/bin:/usr/sbin
            LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
            export PATH  LD_LIBRARY_PATH
            
            重启开发板,发现命令提示符前面显示用户名和主机名

 三,制作可用于烧录的文件系统镜像
    1, nand flash的移植

1》拷贝驱动源码文件到内核源码中:

            1) 将s3c_nand.c拷贝到:\\192.168.7.8\farsight\s5pv210\kernel\linux-3.0.8\drivers\mtd\nand
            2) 将regs-nand.h拷贝到:\\192.168.7.8\farsight\s5pv210\kernel\linux-3.0.8\arch\arm\mach-s5pv210\include\mach
           

 2》修改    drivers/mtd/nand/Kconfig
                添加以下内容:    --------参考2410的配置
                config MTD_NAND_S3C
                    tristate "NAND Flash support for Samsung S3C S5PV210 SoCs"
                    depends on ARCH_S5PV210
                    help
                      This enables the NAND flash controller on the S5PV210 SoCs

                      No board specific support is done by this driver, each board
                      must advertise a platform_device for the driver to attach.

                config MTD_NAND_S3C_DEBUG
                    bool "Samsung S5PV210 NAND driver debug"
                    depends on MTD_NAND_S3C
                    help
                      Enable debugging of the S3C NAND driver

                config MTD_NAND_S3C_HWECC
                    bool "Samsung S5PV210 NAND Hardware ECC"
                    depends on MTD_NAND_S3C
                    help
                      Enable the use of the controller's internal ECC generator when
                      using NAND. Early versions of the chips have had problems with
                      incorrect ECC generation, and if using these, the default of
                      software ECC is preferable.
        
 3》修改Makefile
                21 obj-$(CONFIG_MTD_NAND_S3C)          += s3c_nand.o
 4》修改平台相关代码
            vim arch/arm/mach-s5pv210/mach-smdkv210.c
            1)包含一下头文件:
                #include <linux/mtd/mtd.h>
                #include <linux/mtd/nand.h>
                #include <linux/mtd/nand_ecc.h>
                #include <linux/mtd/partitions.h>
                #include <plat/nand.h>
            2) 添加平台设备
            /* Nand Flash Support */
                static struct mtd_partition s5pv210_nand_part[] = {
                      [0] ={
                            .name = "myuboot",
                            .offset = 0x0,
                            .size = SZ_1M,
                      },
                      [1] ={
                            .name = "kernel",
                            .offset = MTDPART_OFS_APPEND,
                            .size = SZ_1M * 4,
                      },
                      [2] ={
                            .name = "rootfs",
                            .offset = MTDPART_OFS_APPEND,
                            .size = SZ_1M * 16,
                      },
                      [3] ={
                            .name = "userdata",
                            .offset = MTDPART_OFS_APPEND,
                            .size = SZ_1M * 16,
                      },
                      [4] ={
                            .name = "usr spec",
                            .offset = MTDPART_OFS_APPEND,
                            .size = MTDPART_SIZ_FULL,
                      },
                };
                struct s3c_nand_mtd_info s5pv210_nand_mtd_part_info = {
                      .chip_nr = 1,
                      .mtd_part_nr = ARRAY_SIZE(s5pv210_nand_part),
                      .partition = s5pv210_nand_part,
                };
                static struct resource s5pv210_nand_resource[] = {
                      [0] = {
                            .start = 0xB0E00000,
                            .end = 0xB0E00000 + SZ_1M,
                            .flags = IORESOURCE_MEM,
                      }
                };
                struct platform_device s5pv210_device_nand = {
                      .name = "s5pv210-nand",
                      .id = -1,
                      .num_resources = ARRAY_SIZE(s5pv210_nand_resource),
                      .resource = s5pv210_nand_resource,        //nand控制寄存器的地址资源
                            .dev = {                  
                                    .platform_data = &s5pv210_nand_mtd_part_info,         // 特殊的平台数据,分区表
                            }
                };

            3)添加平台设备列表
                在smdkv210_device[]结构体数组中添加如下内容:

                    #if defined(CONFIG_MTD_NAND_S3C)
                            &s5pv210_device_nand,
                    #endif?

                修改arch/arm/plat-samsung/include/plat/nand.h添加如下内容:
                struct s3c_nand_mtd_info{
                      uint chip_nr;
                      uint mtd_part_nr;
                      struct mtd_partition *partition;
                };

                修改include/linux/mtd/partitions.h
                添加
                extern    int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
                ?
                修改arch/arm/mach-s5pv210/clock.c中结构体在最后添加如下代码(加粗部分)
                    static struct clk init_clocks_off[] = {
                    {
                                    。。。。。。
                                  .ctrlbit      = (1 << 0),
                          },{
                                .name = "nandxl",
                                      .id = -1,
                                      .parent = &clk_hclk_psys.clk,
                                      .enable = s5pv210_clk_ip1_ctrl,
                                      .ctrlbit = (1 << 24),
                          },
                    };
                
5》配置内核
            
            
             Device Drivers  --->
                    <*> Memory Technology Device (MTD) support  --->  
                        <*>   Direct char device access to MTD devices
                        -*-   Common interface to block layer for MTD 'translation layers'
                         <*>   Caching block device access to MTD devices
                        
                         <*>   NAND Device Support  --->
                                <*>   NAND Flash support for Samsung S3C S5PV210 SoCs
                                 [*]     Samsung S5PV210 NAND Hardware ECC  
            File systems  --->
                    [*] Miscellaneous filesystems  --->
                             <*>   Journalling Flash File System v2 (JFFS2) support
                              <*>   Compressed ROM file system support (cramfs)
        6》重新编译内核,并拷贝到/tftpboot中
                make -j2
                 cp arch/arm/boot/zImage /tftpboot/
        7》重启开发板,观察
             S3C NAND Driver, (c) 2008 Samsung Electronics
            S3C NAND Driver is using hardware ECC.
            NAND device: Manufacturer ID: 0xec, Chip ID: 0xd3 (Samsung NAND 1GiB 3,3V 8-bit)
            Creating 5 MTD partitions on "s5pv210-nand":
            0x000000000000-0x000000100000 : "myuboot"
            0x000000100000-0x000000500000 : "kernel"
            0x000000500000-0x000001500000 : "rootfs"
            0x000001500000-0x000002500000 : "userdata"
            0x000002500000-0x000040000000 : "usr spec"
        查看分区信息:
            [[email protected] /]# cat proc/partitions
            major minor  #blocks  name

              31        0       1024 mtdblock0
              31        1       4096 mtdblock1
              31        2      16384 mtdblock2
              31        3      16384 mtdblock3
              31        4    1010688 mtdblock4

2,制作可烧录的文件系统镜像
        1》linux内核支持的文件系统镜像种类
                cramfs    -------   只读压缩的文件系统镜像 ,适用于nand
                jffs2     -------   可读写压缩的文件系统镜像
                yaffs -----------   不压缩可读写的文件系统镜像,适用于nand
        2》制作cramfs文件系统镜像
                [email protected]:/opt$ mkfs.cramfs myrootfs/ rootfs.cramfs
            将rootfs.cramfs拷贝到/tftpboot/
                [email protected]:/opt$ cp rootfs.cramfs /tftpboot/
            重启开发板,在uboot中烧录文件系统镜像
                FS210 # tftp 20008000 rootfs.cramfs
                FS210 # nand erase 0x500000 0x1000000
                FS210 # nand write 20008000 0x500000 0x1000000
            重新配置uboot参数
                    FS210 # set bootargs console=ttySAC0,115200 init=/linuxrc root=/dev/mtdblock2 rootfstype=cramfs ip=192.168.7.5
                    FS210 # sa
            测试:
                重启开发板,进入系统后创建一个文件:
                    [[email protected] /]# touch 1.txt
                    touch: 1.txt: Read-only file system
        3》制作jffs2文件系统镜像
            安装mtd工具:
                sudo apt-get install mtd-utils
            制作jffs2文件系统:
                [email protected]:/opt$ mkfs.jffs2 -r myrootfs -o rootfs.jffs2 -e 0x20000 --pad=0x400000 -n
                    -e      nand块大小
                    -pad    rootfs.jffs2指定为多大,和分区大小一致 ------该选项可以不写,时可选的
                    -n       不打印不必要的调试信息
            将rootfs.jffs2拷贝到/tftpboot/
                [email protected]:/opt$ cp rootfs.jffs2 /tftpboot/
            重启开发板,在uboot中烧录文件系统镜像
                FS210 # tftp 20008000 rootfs.jffs2
                FS210 # nand erase 0x500000 0x1000000
                FS210 # nand write 20008000 0x500000 0x1000000
            重新配置uboot参数
                FS210 # set bootargs console=ttySAC0,115200 init=/linuxrc root=1f02 rootfstype=jffs2 ip=192.168.7.5
                FS210 # sa
            测试:
                重启开发板,进入系统后创建一个文件:
                [[email protected] /]# touch 1.txt
                [[email protected] /]# ls
                1.txt    dev      home     linuxrc  opt      root     sys      usr
                bin      etc      lib      mnt      proc     sbin     tmp

            4》混合烧录
            1) 在 /myrootfs/etc/init.d/rcS中添加以下内容:
                    
                    echo "-------ready to mount /dev/mtdblock3 to /home  -------------"
                    /bin/mount -t jffs2 /dev/mtdblock3 /home
            2) 重新制作根文件系统镜像
                生成: rootfs.cramfs
                        mkfs.cramfs myrootfs rootfs.cramfs
                将rootfs.cramfs拷贝到/tftpboot中
                        cp rootfs.cramfs /tftpboot/
                在uboot中烧录文件系统镜像
                        FS210 # tftp 20008000 rootfs.cramfs
                        FS210 # nand erase 0x500000 0x1000000
                        FS210 # nand write 20008000 0x500000 0x1000000
            3) 再制作一个空的文件系统,格式为jffs2
                     mkdir userdata
                     mkfs.jffs2 -r userdata -o userdata.jffs2 -e 0x20000 --pad=0x400000 -n
                     cp userdata.jffs2 /tftpboot/
            4) 将userdata.jffs2烧录到开发板的nand中
                        0x000000000000-0x000000100000 : "myuboot"
                        0x000000100000-0x000000500000 : "kernel"
                        0x000000500000-0x000001500000 : "rootfs"
                        0x000001500000-0x000002500000 : "userdata"
                        0x000002500000-0x000040000000 : "usr spec"
                        
                        FS210 # tftp 20008000 userdata.jffs2
                        FS210 # nand erase 0x1500000 0x1000000
                        FS210 # nand write 20008000 0x1500000 0x1000000
            重新配置uboot参数
                FS210 # set bootargs console=ttySAC0,115200 init=/linuxrc root=/dev/mtdblock2 rootfstype=cramfs ip=192.168.7.5
                FS210 # sa
     3,内核的烧录
            在uboot中:
            1》通过网络烧录内核镜像
                FS210 # tftp 20008000 zImage
                FS210 # nand erase 0x100000 0x400000
                FS210 # nand write 20008000 0x100000 0x400000
            2》配置uboot参数:
                FS210 # set bootcmd nand read 0x40008000 0x100000 0x400000 \; bootm 0x40008000
                FS210 # sa

    

3,烧录内核:
        FS210 # tftp 0x40008000 zImage
        FS210 # nand erase 0x100000  0x400000
        FS210 # nand write 0x40008000  0x100000  0x400000
    
        启动的时候去从nand中加载内核:
            FS210 # set bootcmd nand read 0x40008000 0x100000  0x400000 \; bootm 0x40008000
            
            android系统的结构:

android驱动学习(1)
   etc结构:

android驱动学习(1)
            
    根文件系统目录:

android驱动学习(1)
    
    镜像焼写:

android驱动学习(1)