/>
一、获得源码
按照以下步骤找到并下载源码:
二、建立Source Insight工程
1、建立一个Source Insight以方便阅读及修改代码
在解压出来的目录里新建si文件夹并把当前路径复制下来I:\毕业班\linux-3.4.2\si
然后确定
进入arch目录进入arm目录
点OK等待文件同步完成,至此
Source Insight
工程建立完成。
三、编译初试
把代码放到linux虚拟机下,解压出来:
找到
修改为:
编译最新内核需要较高的编译器我们使用的编译器为gcc version 4.3.3
使用命令查看编译器版本:
使用默认配置文件、查看linux中有哪些默认的配置文件
由于我们的单板的cpu是anr架构的所以我们进入arm目录下的配置文件夹
ls查看:发现有许多的默认配置文件其中一部分如下:
这里我们使用s3c2410_defconfig文件作为默认配置信息:
返回主目录
出现下列信息则证明配置成功
查看生产的配置文件
编译看能不能编译成功:
编译成功:
先用openjtag或者其他方法把u-boot下载到nandflash上
然后:设置参数:
set ethaddr 00:12:34:56:ab:cd; set ipaddr 192.168.1.119; set serverip 192.168.1.123
set 'nand read 30000000 kernel;bootm 30000000'
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
set machid 16a
save
然后把内核下载到RAM0x32000000的地址上然后跳转到该地址执行:
SMDK2410 # tftp 32000000 uImage
SMDK2410 # bootm 32000000
内核有信息输出但是显示乱码:
原因是配置smdk2440单板的时钟出错、来我们跟着山东哥以前寻找出错的地方:
我们这个内核支持很多的单板,判断是什么单板内核是通过判断u-boot传入的machid来判断的,
我们可以将machid设置成一个很大的值看它支持多少种单板:
重启开发板:
SMDK2410 # set machid 123456
SMDK2410 # tftp 32000000 uImage
SMDK2410 # bootm 32000000
这就是我们的内核支持的所有单板。
打开文件: i:\毕业班\linux-3.4.2\arch\arm\mach-s3c24xx\Mach-smdk2440.c
搜索:smdk2440_map_io该函数如下
这里我们注意到s3c24xx_init_clocks(16934400);这句话有问题初始化时钟频率,也就是我们的板子上的晶振的频率
我们的TQ2440单板的晶振频率为12M,所以我们应该把它改过来。
[
root@localhost linux-3.4.2]#
vi arch/arm/mach-s3c24xx/mach-smdk2440.c
编译完成后我们把内核下载到开发板上查看结果:
set ethaddr 00:12:34:56:ab:cd; set ipaddr 192.168.1.119; set serverip 192.168.1.123
set 'nand read 30000000 kernel;bootm 30000000'
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
set machid 16a
save
tftp 32000000 uImage
bootm 32000000
串口输出正常
四、修改分区
到这里我们的内核已经启动起来了,但是还是无法挂载根文件系统
在内核代码里面搜索"Boot Agent"
搜索到这么一行信息:
arch/arm/mach-s3c24xx/common-smdk.c:113: .name = "Boot Agent",
我么进入common-smdk.c 113行来看看。
这不正是内核的分区吗?没错内核的分区是已经写死在代码里面的、特别注意的是这里的分区大小应该
和u-boot的分区一致。好,现在我们来修改内核的分区。
在u-boot里面输入 mtd 命令可以查看u-boot的分区大小。
SMDK2410 # mtd
0x00000000-0x00040000 : “u-boot”
0x00040000-0x00060000 : “params”
0x00060000-0x00260000 : “kernel”
0x00260000-0x10000000 : “rootfs”
将common-smdk.c 里面的分区函数修改为:
将修改好后的I:\毕业班\linux-3.4.2\arch\arm\mach-s3c24xx\common-smdk.c文件覆盖到linux上原本的文件
编译:
得到的文件为:
把它下载到开发板上:
set ethaddr 00:12:34:56:ab:cd; set ipaddr 192.168.1.119; set serverip 192.168.1.123
set 'nand read 30000000 kernel;bootm 30000000'
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
set machid 16a
save
tftp 32000000 uImage; bootm 32000000
好的现在分区已经出来了,但是还是无法挂载文件系统,那是不是我们的分区上没有烧写文件系统呢,我们来吧之前的文件系统烧写进去看看能不能正常启动起来。
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000 889bc0
tftp 32000000 uImage; bootm 32000000
发现根文件系统还是无法挂载,原因是内核尝试了很多种格式的文件系统都无法挂接我们当前的文件系统,原因就是
内核还不支持yaffs2文件系统、但是内核已经支持了jffs2文件系统我们现在尝试烧写jffs2文件系统看能不能正常启动。
tftp 30000000 fs_mini_mdev.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 260000 $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
tftp 32000000 uImage; bootm 32000000
到这里文件系统已经挂载上去了,但是还是无法正常启动。
五、制作根文件系统。
在网上获取最新的busybox 然后编译
Busybox Settings --->
Build Options --->
() Cross Compiler prefix (NEW)
编译完成之后我们来安装文件系统
[root@localhost busybox-1.23.0]# make install CONFIG_PREFIX=/home/Nguhyw/system/fs_mini_mdev_new/
刚才建立的空文件夹里边已经有了文件
make install CONFIG_PREFIX=
安装c库:我们的交叉编译工具链的位置是
/opt/EmbedSky/4.3.3/bin
所以我们进入此目录查看:
./arm-none-linux-gnueabi/lib
./arm-none-linux-gnueabi/libc/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/usr/var/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
./lib
其中的两个库是我们需要的那句是:
./arm-none-linux-gnueabi/libc/armv4t/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/lib
我们把这两个库的所有的 .so 文件拷贝到我们刚才建立的文件里边
首先在fs_mini_mdev_new文件夹里新建一个文件夹
[
root@localhost 4.3.3]#
cp ./arm-none-linux-gnueabi/libc/armv4t/lib/*so* /home/Nguhyw/system/fs_mini_mdev_new/lib -d
此时fs_mini_mdev_new下的lib目录就已经有了很多的.so文件了
我们再来拷贝另一个库路径的.so文件
[
root@localhost 4.3.3]#
cp ./arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /home/Nguhyw/system/fs_mini_mdev_new/usr/lib -d
好的同样 ,此时的usr/lib目录下已经有了很多的.so文件
现在我么来创建etc目录,但是我懒得再来重新构建一次了,直接复制以前做好的文件系统里边的etc目录
[
root@localhost fs_mini_mdev_new]#
cp /home/Nguhyw/fs_text_ok/etc ./ -rf
创建其他的空目录
现在我们来制作jffs2映像文件
[
root@localhost system]#
mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_new -o fs_mini_mdev_new.jffs2
制作完成后我们把它烧写到板子上的rootfs分区去。
tftp 30000000 fs_mini_mdev_new.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 260000 $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
tftp 32000000 uImage; bootm 32000000
输出信息如下所示:
根文件系统已经挂载上去了并且已经找到了我们的init程序,但是还是init程序还有点问题无法启动
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004 退出代码0x00000004
0x00000004 ==》SIGILL ==》 illegal instruction 非法指令
编译busybox的时候交叉编译工具链使用的eabi接口我们的内核也应该支持,我们来配置内核,
搜索EABI 在菜单里输入/即可进入搜索界面
现在EABI接口处于未配置状态,也就是没有被编译进内核里面去,我们现在来配置它。
Kernel Features --->
[*] Use the ARM EABI to compile the kernel
保存退出。
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
tftp 32000000 uImage_eabi; bootm 32000000
六、支持YAFFS文件系统
YAFFS文件系统是专门为nand flash设计的一个文件系统,但是很遗憾yaffs的文件系统的源码并没有合并到linux的内核源码里面去,需要
我们自己手动添加。
1. 获得源码
百度上搜索yaffs
如果系统没有安装git命令的话那需要先安装这里提供山东哥提供的ubunt的安装方法
2. 打补丁
[root@localhost yaffs2]# ./patch-ker.sh c m /home/Nguhyw/system/linux-3.4.2
File systems --->
[*] Miscellaneous filesystems --->
<*> yaffs2 file system support
保存退出。
编译:
编译出错
把yaffs补丁上去的源码 /home/Nguhyw/system/linux-3.4.2/fs/yaffs2 放到Source Insight 里边根据错误信息进行查阅修改
第一个错误:fs/yaffs2/yaffs_vfs.c:2514: error: 'struct mtd_info' has no member named 'sync'
查看mtd结构体后发现,sync成员被改成了_sync
多了一个下划线,那么我们来修改为:
错误信息:
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'
修改:
好的,保存修改 yaffs_vfs.c 并覆盖到linux上去,
错误信息:fs/yaffs2/yaffs_mtdif.c:42: error: 'struct mtd_info' has no member named 'erase'
修改:打开yaffs_mtdif.c 跳转到42行,添加下划线修改为:
输出的错误信息为:
根据上面的经验我们呢可以知道这里也是缺省下划线导致的。来我们一行一行的进行修改。
fs/yaffs2/yaffs_mtdif1.c:138: error: 'struct mtd_info' has no member named 'write_oob'
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:291: error: 'struct mtd_info' has no member named 'block_markbad
fs/yaffs2/yaffs_mtdif1.c:341: error: 'struct mtd_info' has no member named 'block_isbad'
又TMD有错误,有完没完啊!改!谁叫我们是社会的底层劳动者呢。
fs/yaffs2/yaffs_mtdif2.c:90: error: 'struct mtd_info' has no member named 'write_oob'
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:218: error: 'struct mtd_info' has no member named 'block_markbad'
fs/yaffs2/yaffs_mtdif2.c:237: error: 'struct mtd_info' has no member named 'block_isbad'
终于编译成功,ok那我们把这个编译好了的内核烧写到开发板上看这回能不能支持yaffs文件系统的启动。
在烧写之前我们先来制作一个yaffs文件映像
[
root@localhost system]# mkyaffs2image fs_mini_mdev_new fs_mini_mdev_new.yaffs2
tftp 30000000 fs_mini_mdev_new.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000 $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
tftp 32000000 uImage; bootm 32000000
OK 到这里启动成功。
但是山东哥的视频里是没有启动成功的原因是它之前制作的u-boot里面还有bug,这也是个知识点,那么我们也来记录一下吧:
在u-boot代码里的nand_util.c 里面进行修改
七、由于内核现在的二进制文件达到了了2.35M ,而我们的kernel分区只分出了2M的内存空间,所以我们需要进行内核的裁剪,使他变小。
或者也可以直接修改分区,两种方法都可以,先来看内核裁剪。
System Type --->
SAMSUNG S3C24XX SoCs Support --->
File systems --->
保存退出:
妈得怎么改都是那么大现在还是有2.18M 而山东哥的视频里只有2.09M 毛线,搞毛啊!
算了,自己来修改分区好了。
设置参数
set ethaddr 00:12:34:56:ab:cd; set ipaddr 192.168.1.119; set serverip 192.168.1.123
set 'nand read 30000000 kernel;bootm 30000000'
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
set machid 16a
save
或使用uboot来更新自己: tftp 30000000 u-boot_tq2440.bin; nand erase.part u-boot; nand write 30000000 u-boot
启动uboot,用它来烧写内核、FS
tftp 30000000 uImage; nand erase.part kernel; nand write 30000000 kernel
tftp 30000000 fs_mini_mdev_new.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 0x00460000 $filesize
因为uImage这个文件的大小超过了2M所以无法运行起来。
首先是u-boot
改好后编译即可。
再次是linux内核
linux-3.4.2\arch\arm\mach-s3c24xx\Common-smdk.c
OK至此 linux内核移植完成。
八、制作补丁
[
root@localhost system]# diff -urN linux-3.4.2 linux-3.4.2_tq2440 > linux-3.4.2_tq2440.patch
使用:
[
root@localhost linux-3.4.2]# cp ../linux-3.4.2_tq2440/config_ok ./.config
制作u-boot补丁:
[
root@localhost system]# mv u-boot-2012.04.01 u-boot-2012.04.01_tq2440_ok
[
root@localhost system]# diff -urN u-boot-2012.04.01 u-boot-2012.04.01_tq2440_ok > u-boot-2012.04.01_tq2440_ok.patch
使用补丁:
[
root@localhost u-boot-2012.04.01]# patch -p1 < ../u-boot-2012.04.01_tq2440_ok.patch
set bootargs console=ttySAC0,115200 root=/dev/nfs nfsroot=192.168.1.110:/home/Nguhyw/fs_1 ip=192.168.1.119:192.168.1.110:192.168.1.1:255.255.255.0::eth0:off
课程图片: