转自:http://blog.chinaunix.net/uid-22609852-id-3519678.html
1.修改Makefile
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
[root: linux-3.8.2]# make mini2440_defconfig
执行
make uImage
用上文移植的uboot20120401来启动这次编译的内核。
将uImage拷贝到tftp服务器共享目录
然后在开发板上
tftp 32000000 uImage-new
bootm 32000000
发现启动后是乱码
应该是串口波特率不一致导致的
uboot设置下启动参数
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
再次执行
tftp 32000000 uImage-new
bootm 32000000
系统启动了,因为本人用的是1G的nand, 分区可以修改一下更合理。
另外,root分区不存在文件系统还需要烧写文件系统
2.烧写文件系统
[root: linux-3.8.2]# grep "u-boot-env" * -nR
Binary file arch/arm/mach-s3c24xx/mach-mini2440.o matches
arch/arm/mach-s3c24xx/mach-mini2440.c:255: .name = "u-boot-env",
修改为
static struct mtd_partition mini2440_default_nand_part[] __initdata = {
[0] = {
.name = "u-boot",
.size = SZ_256K,
.offset = 0,
},
[1] = {
.name = "u-boot-env",
.size = SZ_128K,
.offset = SZ_256K,
},
[2] = {
.name = "kernel",
/* 5 megabytes, for a kernel with no modules
* or a uImage with a ramdisk attached */
.size = SZ_1M * 5,
.offset = MTDPART_OFS_APPEND,
},
[3] = {
.name = "root",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
再次make uImage并将uImage拷贝到自己的tftp服务器共享目录
烧写jffs2(假定已制作号的文件系统名为my_rootfs)
(
如若要烧写yaffs文件系统,需要修改之前移植的uboot20120401中mini2440.h
打开宏定义CONFIG_CMD_NAND_YAFFS
重新烧写uboot,这样才能使用nand write.yaffs 烧写yaffs文件系统。
tftp 30000000 my_rootfs.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 560000 791340
其中560000是rootfs开始存放的offset地址
如果自己使用的uboot支持yaffs则可免此步,后面也给出了打开yaffs宏的补丁
)
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
tftp 30000000 my_rootfs.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 560000 $filesize
tftp 32000000 uImage-new
bootm 32000000
3.自制文件系统
3.1 编译busybox
下载:最新的busybox-1.20.2.tar.bz2
解压:tar xjf busybox-1.20.2.tar.bz2
从busybox根目录下vi INSTALL可以看到编译busybox的步骤
The BusyBox build process is similar to the Linux kernel build:
make menuconfig # This creates a file called ".config"
make # This creates the "busybox" executable
make install # or make CONFIG_PREFIX=/path/from/root install
3.1.1 make menuconfig修改编译前缀
按/搜索"compile"发现
│ Symbol: CROSS_COMPILER_PREFIX [=]
│ Prompt: Cross Compiler prefix
│ Defined at Config.in:590
│ Location:
│ -> Busybox Settings
│ -> Build Options
找到编译前缀的位置加上arm-linux-
-> Busybox Settings
-> Build Options
-> (arm-linux-) Cross Compiler prefix
或者直接
vi .config
修改CONFIG_CROSS_COMPILER_PREFIX="arm-linux-"
3.1.2
make
创建一个文件系统文件夹
mkdir /home/tftproot/my_rootfs -p
3.1.3 安装busybox
make install CONFIG_PREFIX=/home/tftproot/my_rootfs
3.2 安装glibc库
3.2.1 从本机交叉工具链拷贝动态链接库
[root: busybox-1.20.2]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/FriendlyARM/toolschain/4.4.3/bin
cd /opt/FriendlyARM/toolschain/4.4.3/
[root: 4.4.3]# ls
arm-none-linux-gnueabi bin include lib libexec man share
cd arm-none-linux-gnueabi
ls -l发现lib -> .//sys-root/lib
即我们需要拷贝/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/sys-root/lib下面的库
mkdir /home/tftproot/my_rootfs/lib -p
cp /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/sys-root/lib/*.so* /home/tftproot/my_rootfs/lib -d
mkdir /home/tftproot/my_rootfs/usr/lib -p
cp /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/sys-root/usr/lib/*.so* /home/tftproot/my_rootfs/usr/lib -d
(其实很多库可以裁剪掉)
3.2.2 构建其它目录
查看busybox下的examples/inittab
发现没有/etc/inittab也会自行下列默认行为
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
但还是把它加上,还要加一个串口信息
mkdir /home/tftproot/my_rootfs/etc -p
vi /home/tftproot/my_rootfs/etc/inittab
输入
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
保存
chmod +x /home/tftproot/my_rootfs/etc/init.d/rcS
其中
/etc/init.d/rcS是系统启动执行的第一个脚本
mkdir /home/tftproot/my_rootfs/etc/init.d -p
vi /home/tftproot/my_rootfs/etc/init.d/rcS
输入
#!/bin/sh
ifconfig eth0 169.254.252.204
#挂载文件系统,见etc/fstab
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
保存,加上可执行权限
chmod +x /home/tftproot/my_rootfs/etc/init.d/rcS
vi /home/tftproot/my_rootfs/etc/fstab 输入
#device mount-point type options 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
保存
创建设备文件
mkdir /home/tftproot/my_rootfs/dev -p
cd /home/tftproot/my_rootfs/dev
mknod console c 5 1
mknod null c 1 3
创建其他目录
cd /home/tftproot/my_rootfs
mkdir proc mnt tmp sys root
3.3 制作jffs2
mkfs.jffs2 -n -s 2048 -e 128KiB -d /home/tftproot/my_rootfs -o my_rootfs.jffs2
-n:不要在擦除块上加清除标志
-s 2048:一页大小2048B
-e 128KiB:擦除块大小128KB
-d:制定根文件系统目录
-o:输出文件
(可能提示先安装mtd-utils:apt-get install mtd-utils)
制作完成
实验uboot启动内核后使用jffs2文件系统
注意开发板的启动参数设置:
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
tftp 30000000 my_rootfs.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 560000 $filesize
tftp 32000000 uImage-new
bootm 32000000
3.4 制作yaffs
3.4.1 获取yaffs
git clone git://www.aleph1.co.uk/yaffs2
(可能需要先 apt-get install git-core)
3.4.2 给内核打yaffs补丁
cd yaffs-dir
./patch-ker.sh c m linux-tree 比如 ./patch-ker.sh c m /home/profiles/linux-3.8.2.tar/linux-3.8.2
3.4.3 配置内核使支持yaffs
搜索YAFFS
-> File systems
│ -> Miscellaneous filesystems (MISC_FILESYSTEMS [=y])
│ (1) -> yaffs2 file system support (YAFFS_FS [=n])
按路径找到yaffs2 file system support
使(*)yaffs2 file system support
make uImage
有错误
fs/yaffs2/yaffs_vfs.c:440: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_vfs.c:441: 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:480: error: unknown field 'write_super' specified in initializer
fs/yaffs2/yaffs_vfs.c:480: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_evict_inode':
fs/yaffs2/yaffs_vfs.c:875: error: implicit declaration of function 'end_writeback'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_do_sync_fs':
fs/yaffs2/yaffs_vfs.c:2205: error: 'struct super_block' has no member named 's_dirt'
fs/yaffs2/yaffs_vfs.c:2216: error: 'struct super_block' has no member named 's_dirt'
fs/yaffs2/yaffs_vfs.c:2218: error: 'struct super_block' has no member named 's_dirt'
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_touch_super':
fs/yaffs2/yaffs_vfs.c:2526: error: 'struct super_block' has no member named 's_dirt'
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
fs/yaffs2/yaffs_vfs.c:2976: error: 'struct super_block' has no member named 's_dirt'
struct mtd_info定义的函数前都加了下划线,如mtd->sync应改为mtd->_sync
...
if (mtd->_sync)
mtd->_sync(mtd);
...
yaffs_trace(YAFFS_TRACE_OS, " erase %p", mtd->_erase);
yaffs_trace(YAFFS_TRACE_OS, " read %p", mtd->_read);
yaffs_trace(YAFFS_TRACE_OS, " write %p", mtd->_write);
yaffs_trace(YAFFS_TRACE_OS, " readoob %p", mtd->_read_oob);
yaffs_trace(YAFFS_TRACE_OS, " writeoob %p", mtd->_write_oob);
yaffs_trace(YAFFS_TRACE_OS, " block_isbad %p", mtd->_block_isbad);
yaffs_trace(YAFFS_TRACE_OS, " block_markbad %p", mtd->_block_markbad);
...
但是还是有错误
fs/yaffs2/yaffs_vfs.c:480: error: unknown field 'write_super' specified in initializer
fs/yaffs2/yaffs_vfs.c:875: error: implicit declaration of function 'end_writeback'
fs/yaffs2/yaffs_vfs.c:2205: error: 'struct super_block' has no member named 's_dirt'
fs/yaffs2/yaffs_vfs.c:2216: error: 'struct super_block' has no member named 's_dirt'
fs/yaffs2/yaffs_vfs.c:2218: error: 'struct super_block' has no member named 's_dirt'
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:2526: error: 'struct super_block' has no member named 's_dirt'
fs/yaffs2/yaffs_vfs.c:2967: error: implicit declaration of function 'd_alloc_root'
fs/yaffs2/yaffs_vfs.c:2976: error: 'struct super_block' has no member named 's_dirt'
一个个错误解决:
s/yaffs2/yaffs_vfs.c:480: error: unknown field 'write_super' specified in initializer
在include/linux/fs.h中的struct super_operations定义添加 void (*write_super) (struct super_block *);
fs/yaffs2/yaffs_vfs.c:875: error: implicit declaration of function 'end_writeback'
end_writeback在yaffs_evict_inode中,搜索发现
.evict_inode = yaffs_evict_inode,
SI中搜索"evict_inode",随便打开一个结果
Inode.c (fs\ncpfs): .evict_inode = ncp_evict_inode,
Inode.c (fs\omfs): .evict_inode = omfs_evict_inode,
通过ncp_evict_inode、omfs_evict_inode发现有一个函数和end_writeback近似:clear_inode。
将end_writeback(inode);改成
clear_inode(inode);
fs/yaffs2/yaffs_vfs.c:2205: error: 'struct super_block' has no member named 's_dirt'
在include/linux/fs.h中的struct super_block定义中添加unsigned int s_dirt;
fs/yaffs2/yaffs_vfs.c:2967: error: implicit declaration of function 'd_alloc_root'
SI中搜索“s_root”,发现有sb->s_root = d_make_root(inode);这样的语句
则将错误中d_alloc_root改为d_make_roo
再改几个地方
fs/yaffs2/yaffs_mtdif.c: In function 'nandmtd_erase_block':
fs/yaffs2/yaffs_mtdif.c:42: error: 'struct mtd_info' has no member named 'erase'
fs/yaffs2/yaffs_mtdif1.c: In function 'nandmtd1_write_chunk_tags':
fs/yaffs2/yaffs_mtdif1.c:138: error: 'struct mtd_info' has no member named 'write_oob'
fs/yaffs2/yaffs_mtdif1.c: In function 'nandmtd1_read_chunk_tags':
fs/yaffs2/yaffs_mtdif1.c:200: error: 'struct mtd_info' has no member named 'read_oob'
fs/yaffs2/yaffs_mtdif1.c:223: error: 'struct mtd_info' has no member named 'block_isbad'
fs/yaffs2/yaffs_mtdif1.c: In function 'nandmtd1_mark_block_bad':
fs/yaffs2/yaffs_mtdif1.c:291: error: 'struct mtd_info' has no member named 'block_markbad'
fs/yaffs2/yaffs_mtdif1.c: In function 'nandmtd1_query_block':
fs/yaffs2/yaffs_mtdif1.c:341: error: 'struct mtd_info' has no member named 'block_isbad'
fs/yaffs2/yaffs_mtdif2.c: In function 'nandmtd2_write_chunk_tags':
fs/yaffs2/yaffs_mtdif2.c:90: error: 'struct mtd_info' has no member named 'write_oob'
fs/yaffs2/yaffs_mtdif2.c: In function 'nandmtd2_read_chunk_tags':
fs/yaffs2/yaffs_mtdif2.c:145: error: 'struct mtd_info' has no member named 'read'
fs/yaffs2/yaffs_mtdif2.c:154: error: 'struct mtd_info' has no member named 'read_oob'
fs/yaffs2/yaffs_mtdif2.c: In function 'nandmtd2_mark_block_bad':
fs/yaffs2/yaffs_mtdif2.c:218: error: 'struct mtd_info' has no member named 'block_markbad'
fs/yaffs2/yaffs_mtdif2.c: In function 'nandmtd2_query_block':
fs/yaffs2/yaffs_mtdif2.c:237: error: 'struct mtd_info' has no member named 'block_isbad'
再次make uImage完成
3.4.4 rootfs制成yaffs文件系统并烧写
mkyaffs2image /home/tftproot/my_rootfs my_rootfs.yaffs2
(附件有mkyaffs2image)
在uboot下
tftp 30000000 my_rootfs.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 560000 $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
tftp 32000000 uImage_yaffs
bootm 32000000
完成
4.
制作了u-boot.bin, uImage_yaffs, my_rootfs.yaffs2
重烧整个系统:
j-link烧u-boot.bin
或使用uboot来更新自己:
tftp 30000000 u-boot.bin; nand erase.part u-boot; nand write 30000000 u-boot
启动uboot,参数设置
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
save
用它来烧写内核、FS
tftp 30000000 my_rootfs.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 560000 $filesize
tftp 30000000 uImage_yaffs; nand erase.part kernel; nand write 30000000 kernel
bootm 30000000
其中,u-boot打补丁:
下载u-boot2012.04.01源码解压后
进入u-boot2012.04.01根目录(假定补丁存在上级目录)
patch -p1 < ../u-boot-2012.04.01_with_yaffs.patch
内核打补丁:
下载linux-3.8.2源码解压后
进入linux-3.8.2根目录(假定补丁存在上级目录)
patch -p1 < ../linux-3.8.2_yaffs_mini2440.patch
cp config_mini2440 .config
make uImage