Chinaunix首页 | 论坛 | 博客
  • 博客访问: 233585
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 781
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-08 10:41
个人简介

爱莉清

文章分类

全部博文(80)

文章存档

2018年(1)

2017年(18)

2016年(49)

2015年(7)

2014年(5)

我的朋友

分类: LINUX

2015-07-04 21:43:33

原文地址: />


一、获得源码
按照以下步骤找到并下载源码:
        kernel/
            v3.x/
                linux-3.4.2.tar.bz2 09-Jun-2012 17:32 76M



二、建立Source Insight工程

1、建立一个Source Insight以方便阅读及修改代码
    在解压出来的目录里新建si文件夹并把当前路径复制下来I:\毕业班\linux-3.4.2\si
 
然后确定
进入arch目录进入arm目录

点OK等待文件同步完成,至此Source Insight
工程建立完成。

三、编译初试
把代码放到linux虚拟机下,解压出来:
[root@localhost system]# tar xjf linux-3.4.2.tar.bz2    解压
[root@localhost system]# cd linux-3.4.2        进入主目录
[root@localhost linux-3.4.2]# vi Makefile     
找到
修改为:

编译最新内核需要较高的编译器我们使用的编译器为gcc version 4.3.3 
使用命令查看编译器版本:
[root@localhost linux-3.4.2]# arm-linux-gcc -v
使用默认配置文件、查看linux中有哪些默认的配置文件
[root@localhost linux-3.4.2]# find -name *defconfig
由于我们的单板的cpu是anr架构的所以我们进入arm目录下的配置文件夹
[root@localhost linux-3.4.2]# cd arch/arm/configs/
ls查看:发现有许多的默认配置文件其中一部分如下:
这里我们使用s3c2410_defconfig文件作为默认配置信息:
返回主目录
[root@localhost configs]# cd ../../../
[root@localhost linux-3.4.2]# make s3c2410_defconfig
出现下列信息则证明配置成功
查看生产的配置文件
[root@localhost linux-3.4.2]# vi .config
编译看能不能编译成功:
[root@localhost linux-3.4.2]# make uImage
编译成功:uImage

先用openjtag或者其他方法把u-boot下载到nandflash上
u-boot_new.bin
然后:设置参数:
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
[root@localhost linux-3.4.2]# make uImage
uImage
编译完成后我们把内核下载到开发板上查看结果:
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"

[root@localhost linux-3.4.2]# grep "\"Boot\ Agent\"" * -nR
搜索到这么一行信息:
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上原本的文件
编译:
[root@localhost linux-3.4.2]# make uImage
得到的文件为:
uImage
把它下载到开发板上:
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 然后编译
[root@localhost system]# tar xjf busybox-1.23.0.tar.bz2
[root@localhost system]# cd busybox-1.23.0 
[root@localhost busybox-1.23.0]# make menuconfig
      Busybox Settings --->  
             Build Options --->  
                    () Cross Compiler prefix (NEW)  
 
[root@localhost busybox-1.23.0]# make
编译完成之后我们来安装文件系统
[root@localhost busybox-1.23.0]# make install CONFIG_PREFIX=/home/Nguhyw/system/fs_mini_mdev_new/
[root@localhost busybox-1.23.0]# cd ../
[root@localhost system]# cd fs_mini_mdev_new/
[root@localhost fs_mini_mdev_new]# ls
刚才建立的空文件夹里边已经有了文件
[root@localhost system]# mkdir fs_mini_mdev_new
make install CONFIG_PREFIX=
安装c库:我们的交叉编译工具链的位置是
/opt/EmbedSky/4.3.3/bin
所以我们进入此目录查看:
[root@localhost system]# cd /opt/EmbedSky/4.3.3
[root@localhost 4.3.3]# find -name lib
./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 fs_mini_mdev_new]# mkdir lib
[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 fs_mini_mdev_new]# mkdir usr/lib -p
[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
[root@localhost fs_mini_mdev_new]# mkdir dev
[root@localhost fs_mini_mdev_new]# cd dev/
[root@localhost dev]# mknod console c 5 1
[root@localhost dev]# mknod null c 1 3
创建其他的空目录
[root@localhost fs_mini_mdev_new]# mkdir proc tmp mnt sys root
现在我们来制作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接口我们的内核也应该支持,我们来配置内核,
[root@localhost linux-3.4.2]# make menuconfig
搜索EABI 在菜单里输入/即可进入搜索界面
现在EABI接口处于未配置状态,也就是没有被编译进内核里面去,我们现在来配置它。
        Kernel Features --->   
                 [*] Use the ARM EABI to compile the kernel 
保存退出。
[root@localhost linux-3.4.2]# make uImage
uImage_eabi
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 clone git://
如果系统没有安装git命令的话那需要先安装这里提供山东哥提供的ubunt的安装方法

2. 打补丁
        [root@localhost fs_mini_mdev_new]# cd /home/Nguhyw/system/yaffs2
        [root@localhost yaffs2]# ./patch-ker.sh c m /home/Nguhyw/system/linux-3.4.2
        
        [root@localhost yaffs2]# cd /home/Nguhyw/system/linux-3.4.2
        [root@localhost linux-3.4.2]# ls fs/yaffs2/
        
        [root@localhost linux-3.4.2]# make menuconfig
        File systems --->     
               [*] Miscellaneous filesystems --->   
                         <*> yaffs2 file system support   
        保存退出。
编译:
        [root@localhost linux-3.4.2]# make uImage
         编译出错
                         
        把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上去,
            重新编译:[root@localhost linux-3.4.2]# make uImage
            
            错误信息:fs/yaffs2/yaffs_mtdif.c:42: error: 'struct mtd_info' has no member named 'erase'
        修改:打开yaffs_mtdif.c 跳转到42行,添加下划线修改为:
        
        重新编译:[root@localhost linux-3.4.2]# make uImage
        输出的错误信息为:
        
        根据上面的经验我们呢可以知道这里也是缺省下划线导致的。来我们一行一行的进行修改。
        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'
        
        重新编译:[root@localhost linux-3.4.2]# make uImage
        又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'
        
        
重新编译 :[root@localhost linux-3.4.2]# make uImage
uImage
终于编译成功,ok那我们把这个编译好了的内核烧写到开发板上看这回能不能支持yaffs文件系统的启动。
在烧写之前我们先来制作一个yaffs文件映像
[root@localhost linux-3.4.2]# cd /home/Nguhyw/system/
[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的内存空间,所以我们需要进行内核的裁剪,使他变小。
或者也可以直接修改分区,两种方法都可以,先来看内核裁剪。
[root@localhost linux-3.4.2]# make menuconfig
    System Type --->   
            SAMSUNG S3C24XX SoCs Support --->   
File systems --->     
        

保存退出:

[root@localhost linux-3.4.2]# make uImage

妈得怎么改都是那么大现在还是有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
[root@localhost u-boot-2012.04.01]# vi include/configs/smdk2440.h

改好后编译即可。
再次是linux内核
linux-3.4.2\arch\arm\mach-s3c24xx\Common-smdk.c
OK至此 linux内核移植完成。
八、制作补丁
[root@localhost linux-3.4.2]# cp .config config_ok
[root@localhost linux-3.4.2]# make distclean
[root@localhost linux-3.4.2]# cd ../
[root@localhost system]# mv linux-3.4.2 linux-3.4.2_tq2440
[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]# patch -p1 < ../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 u-boot-2012.04.01]# make distclean
[root@localhost system]# mv u-boot-2012.04.01 u-boot-2012.04.01_tq2440_ok
[root@localhost system]# tar xjf u-boot-2012.04.01.tar.bz2
[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 system]# cd u-boot-2012.04.01
[root@localhost u-boot-2012.04.01]# patch -p1 < ../u-boot-2012.04.01_tq2440_ok.patch
[root@localhost u-boot-2012.04.01]# make smdk2440_config

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
课程图片:


  
阅读(2158) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~