移植环境:
ubuntu14.04
arm-linux-gcc-4.3.2
u-boot使用前面一直的u-boot-2012.04.01
参考:《嵌入式完全开发手册》
windows下sourceInsight建立,包含如下目录:
arch/arm/boot、common、configs、include、kernel、lib、include/
一、修改、编译测试
1.1 修改Makefile
原来: ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
更改后:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
1.2 选择默认配置 : make s3c2410_defconfig
1.3 make uImage
使用NFS下载时,如果有以下问题:
ERROR: Cannot umount
解决办法:
/etc/host 添加:目标板ip,共享目录
10.170.41.110 /work/nfs_root/
1.4查看编译所支持的单板:
virtual-machine:/work/linux-3.4.2/arch/arm$ find -name "mach*.o"
machid 定义处: vi include/generated/mach-types.h
mach-types.h是由以下两个文件生成,存放的是各个板级信息.
/arch/arm/tools/gen-amch-types /arch/arm/tools/mach-types
在这里可以查看,例如mini2440的mach-types中number是1999对应mach-types中的machid就是7cf、smdk2440为16a
u-boot中可以通过:set machid 7cf来设置所选择的单板
1.5烧写内核
nfs或者tftp都可以
nfs 32000000 10.170.41.120:/work/nfs_root/uImage;bootm 32000000
bootm 32000000
1.6启动后乱码
1)修改启动参数:
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
2)修改后选择mini2440可以正常显示,smdk2440晶振选择的不是12M,所以无法正常启动,使用其它板子或者晶振的要注意这里,找到自己开发板定义处,然后修改晶振频率 arch/arm/mach-s3c24xx\mach-smdk2440.c
s3c24xx_init_clock(16934400)
改为
s3c24xx_init_clock(16934400)
1.7烧写文件系统
因为YAFFS2文件系统默认没有编译进内核,所以先烧写JFFS2文件系统
nfs 30000000 10.170.41.120:/work/nfs_root/first_fs.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 260000 3e2724 或者nand write.jffs2 30000000 260000 $filesize
注意分区:mini2440的分区与原来u-boot的分区不同。
到此处内核正常、可以挂载jffs2文件系统、挂载不上的换一个其它的jffs2文件系统试一下。
实在挂载不上也没关系,这里只是确认内核启动是否正常、后面有制作对应的文件系统教程。
二、修改分区
找到各个板子对应的分区文件,然后根据自己的需要做修改就可以了。
因为编译出来的内核超出2M,所以将kernel分区扩展为5M,测试时使用nfs下载到SDRAM中,
可以不用该分区大小,到最后把内核裁剪到2M以下再烧写到nand flash中也可以。
要注意:内核中将分区修改到5M以后,u-boot也要做对应的分区修改,否则使用读写、擦除命令时,对应的分区信息有误。
smdk2440的分区在samsung的smdk公用文件下:
smdk2440:arch\arm\mach-s3c24xx\Common-smdk.c:
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "bootloader",
.size = SZ_256K,
.offset = 0,
},
[1] = {
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = SZ_128K,
},
[2] = {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 0x500000,//或者SZ_2M
},
[3] = {
.name = "rootfs",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
mini2440的在linux-3.4.2\arch\arm\mach-s3c24xx\Mach-mini2440.c
/* NAND Flash on MINI2440 board */
static struct mtd_partition mini2440_default_nand_part[] = {
[0] = {
.name = "bootloader",
.size = SZ_256K,
.offset = 0,
},
[1] = {
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = SZ_128K,
},
[2] = {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 0x500000;//或者SZ_2M
},
[3] = {
.name = "rootfs",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
u-boot中修改分区:
/include/configs/smdk2440.h
#define MTDPARTS_DEFAULT "mtdparts=mini2440-0:256k(u-boot)," \
"128k(params)," \
"5m(kernel)," \
"-(rootfs)" \
三、制作文件系统
1.交叉编译busybox
make menuconfig :设置编译方式 arm-linux-
make
将busybox安装到指定目录: make install CONFIG_PREFIX=/work/nfs_root/fs_mini_mdev_new
2.安装库
查看gcc库:
virtual-machine:/usr/local/arm/4.3.2$ find -name lib
以下是所有的lib库
./arm-none-linux-gnueabi/libc/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/lib
./arm-none-linux-gnueabi/libc/thumb2/usr/lib
./arm-none-linux-gnueabi/libc/thumb2/lib
./arm-none-linux-gnueabi/libc/lib
./arm-none-linux-gnueabi/lib
./lib
选择需要的lib库
mkdir /work/nfs_root/fs_mini_mdev_new/lib
mkdir /work/nfs_root/fs_mini_mdev_new/usr/lib -p //-p可以 一次性创建上下级目录
cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so* /work/nfs_root/fs_mini_mdev_new/lib -d
cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /work/nfs_root/fs_mini_mdev_new/usr/lib -d
3. 构造etc目录
1)构建etc/inittab文件 启动后第一个文件
#/etc/inittab
::sysinit:/etc/init.d/rcS
ttySAC0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
2)/etc/init.d/rcS
#!/bin/sh
ifconfig eth0 10.170.41.110
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
3)etc/fstab
# device mount-point type option dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
4、 构建dev目录
console,null文件:
/fs_mini_mdev_new/etc/dev$ sudo mknod console c 5 1
/fs_mini_mdev_new/etc/dev$ sudo mknod null c 1 3
5. 其他目录
/fs_mini_mdev_new$ mkdir proc tmp mnt sys root
/fs_mini_mdev_new$ls -l
bin dev etc lib linuxrc mnt proc root sbin sys tmp usr
6.生成文件系统
mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_new -o fs_mini_mdev_new.jffs2
烧写测试
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2 //设置启动时挂载的文件系统,yaffs2可以不用设置
nfs 30000000 10.170.41.120:/work/nfs_root/fs_mini_mdev_new.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 260000 $filesize
7. 配置内核支持EABI
测试结果,挂载时有问题
VFS: Mounted root (jffs2 filesystem) on device 31:3.
Freeing init memory: 172K
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
非法指令 : SIGILL illegal instruction
解决办法:
linux: make menuconfig ->kernel feature->加上arm EABI选项
make uImage
重新编译烧写内核就没问题了
四、移植YAFFS文件系统
1.获得源码
安装git: sudo apt-get install git
或者源码:git clone git://www.aleph1.co.uk/yaffs2
2.内核打yaffs2补丁
cd yaffs-dir (/work/yaffs2)
./patch-ker.sh c m linux-tree (/work/linux3.4.2)
3. 配置内核支持YAFFS2
filesystem
miscellaneous filesystem
yaffs2 file system support
4. 编译uImage
make uImage
5. 制作文件系统映像:
mkyaffs2image fs_mini_mdev_new fs_mini_mdev_new.yaffs2
烧写yaffs2文件系统
nfs 30000000 10.170.41.120:/work/nfs_root/fs_mini_mdev_new.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000 $filesize
如果系统没有mkyaffs2image ,可以按照下面步骤制作:
制作mkyaffs2image工具:
cd system/util/Development_util_ok/yaffs2/utils/
make
然后生成mkyaffs2image,放到bin目录加可执行权限
6.启动
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
nfs 32000000 10.170.41.120:/work/nfs_root/uImage_yaffs2
bootm 32000000
7.mini2440测试文件系统挂载成功
这里如果出现挂载不上的话,有可能是u-boot做的有问题、上一篇文章提到u-boot烧写yaffs2文件系统时,缺少判断条件,将oob烧写到正常文件存储区
做一下修改:nand_util.c中
if (!need_skip && !(flags & WITH_DROP_FFS))
改为:
if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags &WITH_YAFFS_OOB))
五、内核裁剪
原内核大小:2486760 2.4M
1.无关的单板
保留mini2440、smdk2440、smdk244***...
2.无关的文件系统
去掉ext2、ext3、....
裁剪完2.2M
下面是可以裁剪的部分,裁剪完不影响内核正常工作,大家可以参照着裁剪一下,裁剪完就2M以下了。
但是3.4.2内核编译完成太大,如果以后还有其它扩展的话肯定超出2M。
所以推荐修改分区,将内核分区扩展一下,记得要修改u-boot对应的分区
usbcore: registered new interface driver libusual ~~~
usbcore: registered new interface driver usbserial
usbcore: registered new interface driver usbserial_generic
USB Serial support registered for generic
usbserial: USB Serial Driver core
usbcore: registered new interface driver ftdi_sio
USB Serial support registered for FTDI USB Serial Device
ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver
usbcore: registered new interface driver pl2303
USB Serial support registered for pl2303
mousedev: PS/2 mouse device common for all mice
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
lp: driver loaded but no devices found
ppdev: user-space parallel port driver
Floating point emulation
<*> FastFPE math emulation (EXPERIMENTAL
Userspace binary formats
<*> Kernel support for a.out and ECOFF binaries
Networking --->
Networking options
[*] IP: multicasting
[*] IP: BOOTP support
<*> IP: IPsec transport mode
<*> IP: IPsec tunnel mode
<*> IP: IPsec BEET mode
[*] TCP: advanced congestion control --->
Networking support
Wireless
[*] Enable LED triggers
Block devices
<*> Loopback device support
SCSI device support
<*> SCSI device support
Cryptographic API
[*] Hardware crypto devices --->
Enable the block layer
[*] Support for large (2TB+) block devices and files
Userspace binary formats
[ ] Write ELF core dumps with partial segments
LCD开机界面
Device Drivers
[ ] Bootup logo --->
六、重烧整个系统
制作u-boot_new.bin, uImage_new, fs_mini_mdev_new.yaffs
依次烧写到开发板中
u-boot
1)使用jtag烧写u-boot_new.bin
2)使用旧的u-boot更新自己
3)烧写uImage、fs
1)nfs
nfs 30000000 10.170.41.120:/work/nfs_root/uImage_new
nand erase.part kernel
nand write 30000000 kernel
2)tftp
tftp 30000000 uImage_new
nand erase.part kernel
nand write 30000000 kernel
七、制作补丁
大家搞完后,一定要记得制作补丁、因为当你换个环境后肯定不会将原工程拷贝过去,而且就算是拷贝也挺麻烦的,使用补丁文件,然后自己下载源码包就可以解决问题了
cp .config config_back保存一下配置文件
make distclean
制作补丁文件:diff -urN linux-3.4.2 linux-3.4.2_100ask > linux-3.4.2_100ask.patch
打补丁:patch -p1 < ../linux-3.4.2_100ask.patch