打印

移植内核3.4到板子

[复制链接]
1961|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Kevin_con|  楼主 | 2015-5-4 20:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
该u-boot是移植在JZ2440V2上的,但移植过程跟其他板子移植是一样的,我是在看韦东山老师视频做的笔记,每一步都很详细,有兴趣的可以看看。有错误的地方请指出,谢谢
bootloader引导内核
1、把内核读入内存
2、设置参数【TAG参数】
3、启动内核 R0寄存器=0 R1=机器ID R2=参数存放的地址
参考自己写bootloader
int main(void)
{
        void (*theKernel)(int zero, int arch, unsigned int params);
        volatile unsigned int *p = (volatile unsigned int *)0x30008000;

        /* 0. 帮内核设置串口: 内核启动的开始部分会从串口打印一些信息,但是内核一开始没有初始化串口 */
        uart0_init();
       
        /* 1. 从NAND FLASH里把内核读入内存 */
        puts("Copy kernel from nand\n\r");
        nand_read(0x60000+64, (unsigned char *)0x30008000, 0x200000);
        puthex(0x1234ABCD);
        puts("\n\r");
        puthex(*p);
        puts("\n\r");

        /* 2. 设置参数 */
        puts("Set boot params\n\r");
        setup_start_tag();
        setup_memory_tags();
        setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
        setup_end_tag();

        /* 3. 跳转执行 */
        puts("Boot kernel\n\r");
        theKernel = (void (*)(int, int, unsigned int))0x30008000;
        theKernel(0, 362, 0x30000100);  
        /*
         *  mov r0, #0
         *  ldr r1, =362
         *  ldr r2, =0x30000100
         *  mov pc, #0x30008000
         */

        puts("Error!\n\r");
        /* 如果一切正常, 不会执行到这里 */

        return -1;
}



内核:你目的是启动运用程序
1、根据R1寄存器的值来确定内核是否支持该机器[或者说是CPU],如果支持,调用该体系的初始化函数进行初始化
2、解析TAG参数
3、装载驱动程序,比如flash,网卡等
4、挂接根文件系统
5、启动运用程序

A、不同的开发板接的外设不一样,比如我们要使用串口打印信息,但开发板选中的晶振不一样,在初始化uart时
        也是不一样的,比如接的网卡等都不一样,初始化函数是不同的,所以,我们需要修改初始化函数

移植过程:
1、解压内核
tar xjf linux-3.4.20.tar.bz2

2、配置内核[可以参考书籍“嵌入式Linux完全开发手册”]
a.修改makefile
vim Makefile
修改
ARCH            ?= arm
CROSS_COMPILE   ?= arm-linux-

b.选择默认的配置
查找一下有哪些默认配置
find -name  "*defconfig"

有一大堆的默认配置,我们可以进去这个目录看一下
cd ./arch/arm/configs

- -支持mini2440了
看下2440有哪些
ls *2440*

看2410

2410更加全面一点
c.make s3c2410_defconfig [ 配置 ]
生成了.config文件,进去看下

支持这些板子

相关帖子

沙发
Kevin_con|  楼主 | 2015-5-4 20:38 | 只看该作者
d.make uImage
e.把生成的uImage下载到板子32000000,然后启动看效果
nfs 32000000 192.168.1.114:/root/work/system_of_new/linux-3.4.20/arch/arm/boot/uImage
注:你得启动nfs服务才能执行这个命令
f.bootm 32000000
看效果

出现一大堆的乱码
g.原因:是传入的机器ID不对,得修改u-boot
我们知道u-boot启动内核的命令是bootm,那么我们就延着bootm追查下去,bootm命令是在cmd_bootm.c文件中实现的
,那么我们这里找到U_BOOT_CMD,在找到bootm命令,看它是怎么调用的

看到bootm调用do_bootm,我那我们进去do_bootm中看它是怎么启动内核的
看到boot_os[i] 这个数组,

这个数组中定义了体系架构启动内核,我们进去看看

第一行就看到do_bootm_linux,进去看看,在这个函数中看到,它调用boot_jump_linux
再进去看看

呐,这就是调用到机器ID了,



从这个函数知道,machid可以从环境变量中获得,没有的话执行默认的machid = gd->bd->bi_arch_number
我们追查bi_arch_number看是否有定义
我们查到,在smdk2410.c中有定义

        gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

它的值是193,这是2410的机器ID,而我们的是2440,所以,我们要修改这个宏。但从上面得出,机器ID可以从环境变量中获得,我们可以试验一下
h.uboot默认的machid gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
  环境变量中获得的machid  
        s = getenv("machid");

如果s = getenv("machid")获得成功,则使用它,否则,使用默认的。
那么,我们可以设置一下machid,现在,我们使用的是193,内核中就根据这个193调用它的初始化函数,
那内核是怎么找到对应的机器呢?
看看内核代码
ls arch/arm/

进入这个目录 cd /arch/arm
find -name "mach*.o"

这些文件都被编译进去内核,从这些文件看出,我们编译的这个Linux.3.4.20支持很多种单板,可以测试一下

在uboot设置机器id: set machid 2343  【 随便设】 然后save

使用特权

评论回复
板凳
Kevin_con|  楼主 | 2015-5-4 20:39 | 只看该作者


Using machid 0x2343 from environment 从环境变量获取machid
Error: unrecognized/unsupported machine ID (r1 = 0x00002343).不支持或不认识的machid
Available machine support:                可用的ID /* 这个编译的内核支持的单板太多了,导致内核非常大,所以还需要裁剪 */
既然是不识别或支持machid那就用个可识别的呗。
使用后

乱码

上面显示的是一些结构体来的,比如smdk2410,看它对应的文件是mach-smdk2410.c,他是根据这个数值[193或者是c1]来找到这个结构体的
这个结构体定义如下

展开这个宏

就会得到相应的信息,具体去inlcude/asm-arm/mach-types.h中查看
i.set machid 16a  save    /* mach-smdk2440.c */
下载内核启动
看结果结果

依然是乱码,有可能是串口波特率的问题
使用mini2440的机器id
set machid 7CF        //mini2440   mach-mini2440.c
设置下串口波特率
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
再次尝试

启动成功
set machid 16a  save    /* mach-smdk2440.c */
set machid 7CF        //mini2440   mach-mini2440.c

这两个函数的差别

它的晶振使用的是16934400,我们板子用的是120000000,所以导致了我们启动内核时会出现乱码,再看下mini2440的

所以,串口乱码的问题已找到,那么,第一步就算完成了:串口能够输出信息

************************************************************************************************
第二步:修改分区表,制作新的文件系统
根据串口打印出来的信息进行修改

在源代码中搜索"Boot Agent"
grep "\"Boot\ Agent"\" * -nR

那我们在arch/arm/mach-s3c24xx/common-smdk.c中看一下/* common通用嘛 */

这就是分区表,我们修改一下,名字不重要,重要的是设置的大小
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"
-----------------------------------------------
按照这样的来写

MTDPART_OFS_APPEND /* 表示当前分区紧接着上个分区 在mtd_partition结构体中定义 */
MTDPART_SIZ_FULL  /* 表示当前分区大小为剩下的flash空间 在mtd_partition结构体中定义 */

修改后编译下载启动



至少分区已经出来了,名字没显示,是不是没有烧写文件系统的原因?
那就烧写文件系统进去看看
烧写文件系统   
nfs 32000000 192.168.1.114:/root/work/system_of_new/linux-3.4.20/arch/arm/boot/uImage
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000  [文件的大小]
bootm 32000000
  No filesystem could mount root, tried:  ext3 ext2 cramfs vfat msdos iso9660 romfs
不支持yaffs2文件系统,但应该支持jffs2文件系统了,搜索一下.config看看有没有编译进去

使用特权

评论回复
地板
Kevin_con|  楼主 | 2015-5-4 20:40 | 只看该作者


搜索YAFFS2是没有的
烧写jffs2文件系统看看
tftp 30000000 fs_mini_mdev.jffs2
nand erase.part rootfs
//nand write.jffs2 30000000 260000  [文件的大小] 这个下载的大小已经有个环境变量保存着了。$filesize
nand write.jffs2 30000000 260000  $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
nfs 32000000 192.168.1.114:/root/work/system_of_new/linux-3.4.20/arch/arm/boot/uImage
bootm 32000000
/* 这个是使用machid 为16a的状况 */

/* 这个是使用machid 为7cf的状况 */

文件系统挂接成功,但貌似还是有问题,终端开启不了。

发现文件系统已经挂载上去了,该文件系统是使用3.4.5的交叉编译器编译的文件系统,是不是交叉编译器的问题呢
在以上的分区表设置是以machid为前提的,我们做这些事情是选择以machid为16a设置【也就是smdk2440】,
但是,如果我们换了别的machid,比如说7CF【mini2440】的。那又得修改相应的文件


制作新的文件系统
使用busybox的版本是1.20,先make menuconfig,在setting中,制定交叉编译器







然后make

安装到/root/work/transplant/rootfs_mini_mdev_new
mkdir bin dev etc lib proc sbin sys usr mnt tmp var
mkdir usr/bin usr/lib usr/sbin lib/modules

1、安装busybox,不会看README文件
make install CONFIG_PREFIX=[要安装的路径] CONFIG_PREFIX
make install CONFIG_PREFIX=/root/work/system_of_new/rootfs_jffs2
2、创建设备文件
cd dev/
mknod -m 666 console c 5 1
mknod -m 666 null c 1 3
cd ..
3、安装/etc
tar -xvzf etc.tar.gz -C /xxx/rootfs
4、安装glib库
cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /root/work/system_of_new/rootfs_jffs2/usr/lib -d -p
cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so* /root/work/system_of_new/rootfs_jffs2/lib -d

/* -d选项就是说原来是什么文件,拷贝过去也是什么文件 */
5、制作jffs2文件系统
mkfs.jffs2 -n -s 2048 -e 128KiB -d rootfs_jffs2 -o rootfs.jffs2
(1)解压zlib-1.2.3.tar.gz
                tar zxf zlib-1.2.3.tar.gz
                cd zlib-1.2.3
                ./configure --shared --prefix=/usr
                make
                make install
(2)编译mtd-utils-05.07.23
                tar zxf mtd-utils-05.07.23
                cd mtd-utils-05.07.23/util
                make
                make install
烧写
nfs 30000000 192.168.16.101:/root/work/transplant/fs_mini_mdev_new.jffs2
nand erase.part rootfs
    nand write.jffs2 30000000 0x00260000 $filesize
启动内核


还是有问题,看内核
搜索一下exitcode
                do_exit()
                SIGILL
SIGILL 信号是cpu在发现非法指令之后发出一个异常,然后由负责处理该异常的内核的ISR对含有这个非法指令的进程发出的。程序收到这个信号,一般就是报 告 illegal instruction 错误信息。
重新配置内核,加上EABI选项,上面说启动不了init,把机器ID改为16a就行了。这问题找了很久,貌似是mini2440的machid不行

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

16

帖子

0

粉丝