cramfs文件系统中ARM9上的移植
?
linux-2.6内核已经支持S3C2410处理器的多种硬件板,我们可以参考SMDK2410参考板来移植开发板的内核。 ? 实验 步骤: (1)准备工作 (2)修改顶层Makefile (3)添加分区 (4)添加devfs (5)配置编译内核 ? 一、准备工作 建立工作目录 ,下载源码,安装交叉工具链,步骤如下。 mkdir / root /build_kernel cd /root/build_kernel wget -c http://www.kernel.org/pub/linux/kernel/v2.6/linux2.6.14.1.tar.bz2 tar jxvf linux2.6.14.1.tar.bz2 或者到上面的网址去下载 ? 二、 修改 顶层 Makefile 修改内核目录树根下的的Makefile ,指明体系结构是arm,交叉编译工具是arm-linux-。 vi Makefile 找到ARCH和CROSS_COMPILE,修改 ARCH ?= arm CROSS_COMPILE ?= /usr/local/arm/3.4.4/bin/ arm-linux- 保存退出 。 这里使用的交叉工具链是3.4.4版本的交叉工具链,需要自己安装,交叉工具链要用好几个,用别人做好的就可以了,当然自己做也可以,但是比较麻烦。 三、 设置flash分区 此处一共要修改 2 个文件,分别是: arch/arm/mach - s3c2410/devs.c??????? ;指明分区信息 arch/arm/mach - s3c2410/mach-smdk2410.c?? ;指定启动时初始化 ? 3.1指明分区信息 在arch/arm/mach-s3c2410/devs.c文件中: vi arch/arm/mach-s3c2410/devs.c 在arch/arm/mach-s3c2410/devs.c文件添加的内容包括: (1)添加包含头文件。 (2)建立nand flash分区表。 (3)假如分区信息 (4) 建立Nand Flash芯片支持 (5) 加入Nand Flash芯片支持到Nand Flash驱动 ? (1)添加包含头文件。 #include <linux/mtd/partitions.h> #include <linux/mtd/nand.h> #include <asm/arch/nand.h> (2) 建立Nand Flash分区表 /* 一个Nand Flash总共64MB,按如下大小进行分区 */ /* NAND Controller */ static struct mtd_partition partition_info[] ={ { /* 256kB */ name: "boot", size: 0x00040000, offset: 0x0, },{ /*1.75MB */ name: "kernel", size: 0x001C0000, offset: 0x00040000,{ /* 30MB */ name: "root", size: 0x01e00000, offset: 0x00200000, },{ /* 32MB */ name: "user", size: 0x02000000, offset: 0x02000000, } }; name: 代表分区名字 size: 代表flash分区大小(单位:字节) offset: 代表flash分区的起始地址(相对于0x0的偏移) 目标板计划分4个区,分别存放boot,kernel,rootfs以及以便以后扩展使用的用户文件系统空间。 (3) 加入Nand Flash分区 struct s3c2410_nand_set nandset ={ nr_partitions: 4,???????? /* 指明partition_info中定义的分区数目 */ partitions: partition_info,/* 分区信息表*/ }; (4) 建立Nand Flash芯片支持 struct s3c2410_platform_nand superlpplatform={ tacls:0, twrph0:30, twrph1:0, sets: &nandset, nr_sets: 1, }; sets: 支持的分区集 nr_set:分区集的个数 (6) 加入Nand Flash芯片支持到Nand Flash驱动 另外,还要修改此文件中的s3c_device_nand结构体变量,添加对dev成员的赋值 struct platform_device s3c_device_nand = { .name = "s3c2410-nand",?? /* Device name */ .id = 1,?? /* Device ID */ .num_resources = ARRAY_SIZE(s3c_nand_resource), .resource = s3c_nand_resource,/* Nand Flash Controller Registers */ /* Add the Nand Flash device */ .dev = { .platform_data = &superlpplatform } }; name: 设备名称 id: 有效设备编号,如果只有唯一的一个设备为1,有多个设备从0开始计数. num_resource: 有几个寄存器区 resource: 寄存器区数组首地址 dev: 支持的Nand Flash设备 ? 3.2 指定启动时初始化 kernel启动时依据我们对分区的设置进行初始配置. arch/arm/mach - s3c2410/mach - smdk2410.c文件 vi arch/arm/mach - s3c2410/ m ach - smdk2410.c 修改smdk2410_devices[].指明初始化时包括我们在前面所设置的flash分区信息 static struct platform_device *smdk2410_devices[] __initdata = { & s3c_device_usb, & s3c_device_lcd, & s3c_device_wdt, & s3c_device_i2c, & s3c_device_iis, / * 添加如下语句即可 */ & s3c_device_nand, }; 保存,退出。 ? 四、 支持启动时挂载devfs 为了我们的内核支持devfs以及在启动时并在/sbin/init运行之前能自动挂载/dev为devfs文件系统,修改fs/Kconfig文件 vi fs/Kconfig 找到menu "Pseudo filesystems" 添加如下语句: config DEVFS_FS bool "/dev file system support (OBSOLETE)" default y config DEVFS_MOUNT bool "Automatically mount at boot" default y depends on DEVFS_FS ????? ?
cp arch/arm/configs/smdk2410_defconfig .config make smdk2410_defconfig ? make menuconfig 在smdk2410_defconfig基础上,我所增删的内核配置项如下: 这里约定“#”后面的是注释部分。 Loadable module support --> [*] Enable loadable module support [*] Automatic kernel module loading System Type --> [*] S3C2410 DMA support Boot options --> Default kernel command string: noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200 #说明:mtdblock2代表我的第3个flash分区,它是我的rootfs # console=ttySAC0,115200使kernel启动期间的信息全部输出到串口0上. # 2.6内核对于串口的命名改为ttySAC0,但这不影响用户空间的串口编程。 # 用户空间的串口编程针对的仍是/dev/ttyS0等 Floating point emulation --> [*] NWFPE math emulation This is necessary to run most binaries!!! #接下来要做的是对内核MTD子系统的设置 Device Drivers --> Memory Technology Devices (MTD) --> [*] MTD partitioning support #支持MTD分区,这样我们在前面 设置的分区才有意义 [*] Command line partition table parsing #支持从命令行设置flash分区信息,灵活 RAM/ROM/Flash chip drivers --> <*> Detect flash chips by Common Flash Interface (CFI) probe <*> Detect nonCFI AMD/JEDECcompatible flash chips <*> Support for Intel/Sharp flash chips <*> Support for AMD/Fujitsu flash chips <*> Support for ROM chips in bus mapping NAND Flash Device Drivers --> <*> NAND Device Support <*> NAND Flash support for S3C2410/S3C2440 SoC Character devices > [*] Nonstandard serial port support [*] S3C2410 RTC Driver #接下来做的是针对文件系统的设置,本人实验时目标板上要上的文件系统是cramfs,故做如下配置 File systems --> <> Second extended fs support #去除对ext2的支持 Pseudo filesystems --> [*] /proc file system support [*] Virtual memory file system support (former shm fs) [*] /dev file system support (OBSOLETE) [*] Automatically mount at boot (NEW) #这里会看到我们前先修改fs/Kconfig的成果,devfs已经被支持上了 Miscellaneous filesystems --> <*> Journalling Flash File System v2 (JFFS2) support [*]??? JFFS2 write-buffering support [*]??? Advanced compression options for JFFS2 JFFS2 default compression mode (priority)?? --->?? (X) size (EXPERIMENTAL) #选择JFFS2文件系统的压缩格式“size” <*> Compressed ROM file system support (cramfs) #支持 jffs2和 cramfs 文件系统 这里要选你自己做的文件系统是什么,要选上文件系统支持,要不无法启动内核。 Network File Systems --> <*> NFS file system support 保存退出,产生.config文件. ? 编译内核 make 注意:若编译内核出现如下情况 LD .tmp_vmlinux1 armlinuxld: arch/arm/kernel/vmlinux.lds:1439: parse error make: *** [.tmp_vmlinux1] Error 1 解决方法 : 修改 arch/arm/kernel/vmlinux.lds vi arch/arm/kernel/vmlinux.lds 将文件尾 2 条的 ASSERT 注释掉; /* ASSERT((__proc_info_end __proc_info_begin),"missing CPU support") */ /* ASSERT((__arch_info_end __arch_info_begin),"no machine record defined") */ 然后重新 make zImage 即可。 ??? ??? 编译完成后会在arch/arm/boot/目录下生产zImage内核映象。zImage映象是可引导的,压缩的内核映象,就是我们要移植到开发板上的内核映象文件。 ? ? 当时我以为要加u-boot 的头,但是实际证明,不用也是可以引导的,直接把zImage烧到上面的内核分区上即可,用如下命令:先把zImage放到tftp的工作目录下,启动板子,进入u-boot,执行:tftp 0x30008000 zImage (事先要在板子上设置serverip为你的电脑的ip,并确认连上网线),然后执行 nand erase 0x30000 0x1c0000 (表 示把nand flash里面从地址0x30000开始的0x1c0000个字节的内容全部擦除,因为nand flash是要先擦除才可以写入的,我们通过tftp下载到板子上的东西是放在SDRAM上的,掉电即消失,所以我们要把它们放到flash上。)?? 其中的 0x1c0000 可以改的, 0x30000 是你内核烧进去的地址,也上面加到内核中的分区对应,这个值也可以改,只要你的内核烧进去以后不会超过你内核的分区。确定内核的大小小于内核分区的大小后可以执行烧内核到flash的命令了: nand write 0x30008000 0x30000 0x1c0000 烧写 完毕后后给出OK的提示,否则就是ERROR,如果是错误的话很有可能就启动不了啦,重新回到上面检查一下吧,或者把错误拿到google或者百度上看一下这个时候内核烧写完毕. ? B usybox下载地址: http://www.busybox.net/downloads/ busybox-1.5.0.tar.bz2 ? 实验步骤: ? 1 建立工作目录 设定工作目录为/root/build_rootfs/,下载busybox到该目录 mkdir /root/build_rootfs ? 2 建立根目录,该目录就是我们要移植到目标板上的目录,对于嵌入式的文件系统,根目录下必要的目录包括bin,dev,etc,usr,lib,sbin。 cd /root/build_rootfs mkdir rootfs cd rootfs mkdir bin dev etc usr lib sbin proc mkdir usr/bin usr/sbin usr/lib ? 3 交叉编译busybox, ? ? ? #解压? tar jxvf busybox-1.5.0.tar.ba2 mv busybox-1.5.0 busybox cd busybox #添加交叉工具链 export PATH=/usr/local/arm/3.3.2/bin:$PATH ? make defconfig make menuconfig #配置时,我们基于默认配置,再配置它为静态编译,安装时不要/usr路径,把Miscellaneous Utilities #下的“taskset”选项去掉,不然会出错。 #如下: Busybox setting ->builds options ->[*] build busybox as a static binary ->installitation options ->[*] don ’ t use /usr Miscellaneous Utilities ―> [?? ] taskset 保存退出。 ? #编译安装 make ARCH=arm CROSS_COMPILE=arm-linux- CONFIG_PREFIX=/root/build_rootfs/rootfs all install ARCH指定平台 CROSS_COMPILE指定交叉编译 CONFIG_PRRFIX指定安装的路径 ? #把安装的linuxrc删除 cd /root/build_rootfs/rootfs rm linuxrc ? 3 copy C库 交叉应用程序的开发需要用到交叉编译的链接库,交叉编译的链接库是在交叉工具链的lib目录下;我们在移植应用程序到我们的目标板的时候,需要把交叉编译的链接库也一起移植到目标板上,这里我们用到的交叉工具链的路径是/usr/local/arm/3.3.2/,所以链接库的目录是/usr/local /arm/3.3.2/lib(本来跟目标板相关的目录是/usr/local/arm/3.3.2/arm-linux,因此要拷贝的链接库应该在/usr/local/arm/3.3.2/arm-linux/lib下,但是此目录的很多链接都是链接到/usr /local/arm/3.3.2/lib目录下的库文件,所以我们从/usr/local/arm/3.3.2/lib目录拷贝库),此目录下有四种类型的文件。 注意:3.4.4版本的交叉工具链的库文件路径是: /usr/local/arm/3.4.4/sysroot/lib 实际的共享链接库 如:libc-2.3.2.so 主修订版本的符合链接 如:libc.so.6 与版本无关的符合链接(链接到主修订版本的符合链接) 如:libc.so 静态链接库包文件 如:libc.a ? 以上四种类型的文件,我们只需要两种:实际的共享链接库;主修订版本的符合链接,还有动态连接器及其符号链接。 ? #进入链接库目录 cd /usr/local/arm/3.3.2/lib #编写一个 shell 文件 , 用于 copy实际的共享链接库;主修订版本的符合链接;动态连接器及其符号链接到目标板根目录下的lib(在这里是/root/)。 vi cp.sh #内容如下: for file in libc libcrypt libdl libm libpthread libresolv libutil do cp $file-*.so /root/build_rootfs/rootfs/lib cp -d $file.so.[*0-9] /root/build_rootfs/rootfs/lib done cp -d ld*.so* /root/build_rootfs/rootfs/li b #保存退出 #第一个cp命令会复制实际的共享库 #第二个cp命令会复制符合链接本身 #第三个cp命令会复制动态连接器及其符合链接 ? #执行刚编写的shell。 source cp.sh #这样就把链接库复制过来了。 ? #接着我们还要缩小复制过来的链接库的体积,如下: arm-linux-strip – s /root/build_rootfs/rootfs/lib/lib* ? ? 5 建立配置文件 这里我们没有添加inittab等文件,我们只是添加了一个c shell初始化时读取的文件。 内核启动的最后,会执行sbin/init程序,init程序在启动的最后会执行/bin/sh,sh在启动的时候会读取/etc/profile文件。关于linux启动流程可以参考: http://www.ibm.com/developerworks/cn/linux/kernel/startup/index.html ? 我们在/etc/profile文件里设定PATH,LD_RARYLIB_PATH环境变量,目的是配置用户程序运行的环境。 cd /root/build_rootfs/rootfs/etc vi profile 内容如下 #!/bin/sh echo "Set seaech library in /etc/profile" export LD_LIBRARY_PATH=/lib echo "Set user path in /etc/profile" export PATH=/bin :/sbin:/usr/bin 保存退出 ? 6 添加一个用户程序 进入工作目录 cd /root/build_rootfs/ 编辑源文件 vi hello.c 内容如下 #include <stdio.h> main() { printf( “ welcome to my rootfs/n ” ); } 保存退出 ? 交叉编译 arm-linux-gcc hello.c – o hello 复制到目标板的根目录 mv hello /root/build_rootfs/rootfs/usr/bin ? 7 制作cramfs映像 我们在光盘资料盘下的“Linux内核源码包和工具/toolchain”可以找到mkcramfs工具,把它复制到“/root/build_rootfs”目录下。 cd /root/build_rootfs/ mkcramfs rootfs rootfs.cramfs rootfs.cramfs就是我们要烧写到目标板的映像文件 ? 8 烧写rootfs.cramfs到2分区,启动开发板,运行hello程序。 将rootfs.cramfs文件拷贝到tftp下载的目录下,如拷贝到linux 系统中的/tftpboot目录; 开发板的u-boot通过tftp命令下载; 根据内核中的分区表来烧写(烧到“root”标记的分区中,即文件系统区);烧写规则同烧写内核(见(一)),先通过tftp下载到SDRAM中然后擦除nand flash,然后再写入nand flash。 烧写好内核和文件系统后,linux2.6即可启动,但是还要在u-boot中设置好参数: #setenv bootcmd nand read 0x30008000 0x40000 0x1c0000 /;go 0x30008000 #setenv bootargs noinitrd root=/dev/mtdblock/3 console=ttySAC0 #saveenv #reset 即可见到linux2.6启动界面。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |