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系统的结构:
etc结构:
根文件系统目录:
镜像焼写: