linux3.4.2内核介绍,S3C2440移植linux3.4.2内核之内核框架介绍及简单修改

本文详细介绍了如何移植Linux3.4.2内核到S3C2440平台,包括配置Makefile、设置机器ID、解决启动时的错误,并通过UBOOT的bootm命令启动内核。在启动过程中,内核首先检查机器ID,然后解析TAG参数,初始化设备,最后跳转到入口点执行。遇到的波特率和晶振频率问题也进行了调整和解决。
摘要由CSDN通过智能技术生成

文章目录

移植Linux3.4.2内核其他文章链接:

uboot启动内核分析

进入cmd_bootm.c,找到对应的bootm命令对应的do_bootm():int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){boot_os_fn *boot_fn;             //boot_fn是个数组函数

... ..boot_fn(0, argc, argv, &images); //调用数组函数

... ...}

boot_os_fn是个typedef型,如下图所示:

c9e9fc74883b7f43c84d1a0df3587df1.png

由于定义了宏CONFIG_BOOTM_LINUX,最终会跳转到do_bootm ->do_bootm_linux()

代码如下所示:int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images){ /* No need for those on ARM */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)   return -1; if (flag & BOOTM_STATE_OS_PREP) {   boot_prep_linux(images);   return 0; } if (flag & BOOTM_STATE_OS_GO) {   boot_jump_linux(images);   return 0; }

boot_prep_linux(images);      //该函数会将各个tag参数保存在指定位置,比如:内存tag、bootargs环境变量tag、串口tag等 boot_jump_linux(images);      //该函数会跳转到内核起始地址 return 0;}

最终跳转到do_bootm ->do_bootm_linux-> boot_jump_linux()static void boot_jump_linux(bootm_headers_t *images){ unsigned long machid = gd->bd->bi_arch_number;     //获取机器ID char *s; void (*kernel_entry)(int zero, int arch, uint params); unsigned long r2; kernel_entry = (void (*)(int, int, uint))images->ep;  //设置kernel_entry()的地址为0x30000000 s = getenv("machid");                     //判断环境变量machid是否设置,若设置则使用环境变量里的值    if (s) {

strict_strtoul(s, 16, &machid);      //重新获取机器ID   printf("Using machid 0x%lx from environment\n", machid);  //使用环境变量的machid }     ... ...r2 = gd->bd->bi_boot_params;     //获取tag参数地址, gd->bd->bi_boot_params在setup_start_tag()函数里被设置 kernel_entry(0, machid, r2);     //跳转到0x30000000,r0=0,r1=机器ID,r2=tag参数地址}

上面的machid默认值为MACH_TYPE_SMDK2410(也就是193),我们也可以在环境变量里设置machid变量

最终,便跳到内核执行代码,步骤如下所示:

1)根据R1(机器ID),来判断内核是否支持该机器,若支持则初始化机器相关函数

2)解析TAG参数,初始化串口,设置内存等

3)挂载根文件系统,并执行应用程序

简单配置内核

修改Makefile,修改配置tar xjf linux-3.4.2.tar.bz2

cd linux-3.4.2/vi Makefile

f264567b8214419c127f47052bf1561c.png

改为ARCH            ?= arm

CROSS_COMPILE   ?= arm-linux-

配置编译cd arch/arm/configs                //由于我们板子是arm板,进入该目录ls  *2440*                            //找到有mini2440_defconfig、ls  *2410*                            //找到有s3c2410_defconfigcd ../../..make s3c2410_defconfig                //配置2410, 更新.config配置文件 make uImage                          //编译,生成uImagecp arch/arm/boot/uImage /work/nfs_root/           //拷贝cd /work/nfs_root/ mv uImage uImage_new

d0d912e504be70ba506c49518edb7515.png

进入.config查看支持的CPUvi .config

27f25b8084d9a6bfe8c4ea4135869ead.png

如上图所示,有我们的2440

编译内核make uImage

报错如下Can't use 'defined(@array)'(Maybe you should just omit the defined? )at kernel/timeconst pl line 373/root/working/Hi3520D SDK V2.0.3.0/osdrv/kernel/linux-30y/kernel/Makefile:140recipe for target kernel/timeconst h failed make【1】:*** 【kernel/timeconst h】 Error 255Makefile:945:recipe for target kernel ' failed

【kernel】 Error 2

解决办法:

将 kernel/timeconst.pl中第373行的 defined0去掉只留下@val就可以了vim kernel/timeconst.pl +373

进入uboot烧写nfs 32000000 192.168.2.106:/work/nfs_root/uImage_new

bootm 32000000

如下图所示,发现串口输出乱码:

cf2ccb7a45a2f1abe0cd01ce7b8cfbec.png

设置机器ID

uboot传递进来的机器ID可以通过环境变量machid来设置

所以任意设置一个ID,这样再次启动内核时,内核识别不出来,就会打印出所有设备对应的机器ID。下面开始测试机器ID是否正确,进入uboot,输入:set machid 33333tftp 32000000 uImage

bootm 32000000

如下图所示,由于内核不支持这个机器ID,所以打印出内核能支持的ID表:

87a45b78261922c8fefd1f0102bdd56b.png

ID所对应的文件为arch/arm/mach-s3c24xx/Mach-smdk2440.c

acccbf9f08734dd02624e68e54e65463.png

MACHINE_START为一个结构体,根据不同的机器ID找到对应的MACHINE_START,调用初始化函数。

由于我们板子是2440,所以测试7cf(mini2440)以及16a(smdk2440)这两个机器ID,是否支持我们开发板。

但是依旧乱码,可能是波特率设置不正确。重新设置下环境变量的波特率set bootargs root=/dev/mtdblock3 console=ttySAC0,115200

再次烧写启动,发现7cf(mini2440)这个ID,有串口输出正常。下面看下16a(smdk2440)为什么串口乱码,进入mach-smdk2440.c( 位arch/arm/mach-s3c24xx)找到问题出在smdk2440_map_io():static void __init smdk2440_map_io(void){ s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_clocks(16934400);             //初始化时钟clock s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));}

修改晶振

由于我们板子上的晶振是12Mhz,而mdk2440_map_io()里,初始化的时钟是基于16934400hz的晶振。所以将:s3c24xx_init_clocks(16934400);             //初始化时钟clock

改为:s3c24xx_init_clocks(12000000);             //初始化时钟clock

然后重新编译uImage:make  s3c2410_defconfig             //将mach-s3c2440.c配置进内核make  uImage

cp uImage /work/nfs_root/ uImage_new

进入uboot,输入:set machid 16a

nfs 32000000 192.168.1.30:/work/nfs_root/uImage_new

bootm 32000000

标签:kernel,machid,boot,bootm,内核,S3C2440,ID,linux3.4

来源: https://blog.51cto.com/u_11934066/2711478

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值