基于FL2440的3.6.6内核移植记录
2016-07-19 16:46
288 查看
一前期准备工作
二kernel sourse的修改
1 由于cross-compile 更改顶层make file下的这两行如下
2 增加自己Machine的macro name和numberUboot中的机器码
3 修改Kconfig和添加c文件
31 增加menuconfig配置项主要修改 archarmmach-s3c24xxKconfig
32 在 archarmmach-s3c24xxMakefile中添加machinec文件的编译控制配置
33 关闭NAND_ECC校验
34 添加machinec源码
三make menuconfig 配置内核
四编译下载
五参考文章
1.1 内核下载
到官网地址选相应的内核下载,我这里参考也选了3.6.6,下载后解压出来,如下:
1.2 编译器的下载和配置
可到Linaro官网选择相应版本下载
解压出来保存
这几项用处是什么?
同目录下有个gen-mach-types的脚本,譔脚本自动用此文件来生成include/generated/mach-types.h头文件见参考2,只举一项内容如下:
因此其各项作用:
machine_is_xxx :定义machine_is_mini2440()
CONFIG_xxxx:用来配置内核编译选项(后面修改Kconfig需要)
MACH_TYPE_xxx :宏定义MACH_TYPE_xxx =number(后面修改mach-class.c文件需要)
number:机器码,用来bootloader控制内核在boot阶段匹配哪个machine_desc(如果内核编译了多个machine的话)
如:当CONFIG_MACH_MINI2440=y时,就定义了相应的machine_is_mini2440()函数,并编译arch/arm/mach-s3c24xx/mach-mini2440.c,此文件将__mach_desc_MINI2440添加到了( __arch_info_begin,__arch_info_end )里。
在内核boot时将从bootloader得到的机器码与MACH_TYPE_xxx匹配就得到__mach_desc_MINI2440描述体了,从而以此描述体里的相应信息启动相应的kernel设备,不然就卡死在“Uncompressing Linux… done, booting the kernel.”之后了。
boot时是如何匹配?
先看看arch/arm/include/asm/mach/arch.h 中的相关结构体
在看编译的设备文件arch/arm/mach-s3c24xx/mach-mini2440.c中最后的MACHINE_START定义
可看到这里定义了一个machine_desc( __mach_desc_MINI2440 )
.nr=MACHINE_TYPE_MINI2440//本质就是机器码number
.name=”MINI2440”
内核启动时如下:
bootloader将机器码等参数传入–飞凌里的boot如下call_linux(0, machine id, runaddr)– kernel接收到后运行如下:start_kernel–> setup_arch(&command_line) –>setup_machine_tags(machine_arch_type)–>for_each_machine_desc(p)
2.3.1 增加menuconfig配置项,主要修改
这是网上流传的方法 ,分析代码发现
只要set->disable_ecc为真就行,追踪下发现在mach-mini2440.c(就是我说的machine.c文件)的NAND分区设置里可以增加此参数,因此我用如下方法修改
成功后启动会出现
- 修改machine名字,不改也行,只要将
- 检查时钟频率:s3c24xx_init_clocks(12000000);
- 依bootloader修改NAND分区
添加LCD配置,我用的是4.3寸屏
在static struct s3c2410fb_display lxa2440_lcd_cfg[] 末加入新增配置如下
然后修改lxa2440_features_str变量
由下面的代码也可知,也可以通过bootloader的启动参数设置(lxa2440=4),
添加触摸设备
添加头文件:#include < plat/ts.h > //新片内核以更改了位置
添加s3c2410_ts_mach_info结构
在初始化
修改
在
System Type –>SAMSUNG S3C24XX SoCs Support —> S3C2440 Boards –>[*] LXA2440 development board,勾除MINI2440
3.2 更改下Kernel Features ,勾上
[*] Provide old way to pass kernel parameters //不同版本位置稍有区别,4.0.0之后的版本好像是在boot option里
因为飞凌的bootloader版本旧,不兼容会导致卡死在Uncompressing 那里。具体分析可看我另一篇 基于FL2440的3.6.6内核移植出现Uncompressing Linux… done, booting the kernel.
添加 触摸驱动
Device Drivers->Input device support —> [] Touchscreens —> <> Samsung S3C2410/generic touchscreen input driver
退出保存
本方法同样适用于4.4.16 ,在4.5.4版本中移植网络有问题,无法NFS启动.照理说只有添加网卡平台设备就行了,可怎么也link up 不了,
3.2 kernel内核中处理器类型的定义mach-types.h文件的生成
二kernel sourse的修改
1 由于cross-compile 更改顶层make file下的这两行如下
2 增加自己Machine的macro name和numberUboot中的机器码
3 修改Kconfig和添加c文件
31 增加menuconfig配置项主要修改 archarmmach-s3c24xxKconfig
32 在 archarmmach-s3c24xxMakefile中添加machinec文件的编译控制配置
33 关闭NAND_ECC校验
34 添加machinec源码
三make menuconfig 配置内核
四编译下载
五参考文章
一、前期准备工作
成功启动的提示信息,可以看出我的编译环境Booting Linux on physical CPU 0 Linux version 3.6.6 (anzyelay@ubuntu) (gcc version 4.9.4 20151028 (prerelease) (Linaro GCC 4.9-2016.02) ) #24 Mon Jul 18 16:17:22 CST 2016 CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177 CPU: VIVT data cache, VIVT instruction cache Machine: LXA2440 Memory policy: ECC disabled, Data cache writeback CPU S3C2440A (id 0x32440001) S3C24XX Clocks, Copyright 2004 Simtec Electronics S3C244X: core 400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256 Kernel command line: root= init=/linuxrc load_ramdisk=0 console=ttySAC0,115200 mem=65536K devfs=mount display =lcd480 root=/dev/nfs nfsroot=192.168.10.5:/home/anzyelay/Desktop/arm/rootfs ip=192.168.10.110:::::eth0
1.1 内核下载
到官网地址选相应的内核下载,我这里参考也选了3.6.6,下载后解压出来,如下:
anzyelay@ubuntu:arm$ tar -xf linux-3.6.6.tar.xz anzyelay@ubuntu:arm$ ls anzyelay@ubuntu:arm$ ls linux-3.6.6 linux-3.6.6.tar.xz anzyelay@ubuntu:arm$
1.2 编译器的下载和配置
可到Linaro官网选择相应版本下载
解压出来保存
/usr/local/arm/4.9.4下,保存位置仅做参考,可自行更改,配置修改这里不做说明了,更改文件
anzyelay@ubuntu:linux-3.6.6-gcc.4.9.4$ ls /usr/local/arm/4.9.4/ arm-linux-gnueabi bin gcc-linaro-4.9-2016.02-manifest.txt include lib libexec share
二、kernel sourse的修改
2.1 由于cross-compile, 更改顶层make file下的这两行如下:
anzyelay@ubuntu:linux-3.6.6-gcc.4.9.4$ vi Makefile 195 ARCH ?=arm 196 CROSS_COMPILE ?=/usr/local/arm/4.9.4/bin/arm-linux-gnueabi-
2.2 增加自己Machine的macro name和number(Uboot中的机器码)
在arch/arm/tools/mach-types文件中添加,anzyelay@ubuntu:linux-3.6.6-gcc.4.9.4$ vi arch/arm/tools/mach-types # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number 363 mini2440 MACH_MINI2440 MINI2440 1999 364 lxa2440 MACH_LXA2440 LXA2440 193
这几项用处是什么?
同目录下有个gen-mach-types的脚本,譔脚本自动用此文件来生成include/generated/mach-types.h头文件见参考2,只举一项内容如下:
#define MACH_TYPE_MINI2440 1999 #ifdef CONFIG_MACH_MINI2440 # ifdef machine_arch_type # undef machine_arch_type # define machine_arch_type __machine_arch_type # else # define machine_arch_type MACH_TYPE_MINI2440 # endif # define machine_is_mini2440() (machine_arch_type == MACH_TYPE_MINI2440) #else # define machine_is_mini2440() (0) #endif
因此其各项作用:
machine_is_xxx :定义machine_is_mini2440()
CONFIG_xxxx:用来配置内核编译选项(后面修改Kconfig需要)
MACH_TYPE_xxx :宏定义MACH_TYPE_xxx =number(后面修改mach-class.c文件需要)
number:机器码,用来bootloader控制内核在boot阶段匹配哪个machine_desc(如果内核编译了多个machine的话)
如:当CONFIG_MACH_MINI2440=y时,就定义了相应的machine_is_mini2440()函数,并编译arch/arm/mach-s3c24xx/mach-mini2440.c,此文件将__mach_desc_MINI2440添加到了( __arch_info_begin,__arch_info_end )里。
在内核boot时将从bootloader得到的机器码与MACH_TYPE_xxx匹配就得到__mach_desc_MINI2440描述体了,从而以此描述体里的相应信息启动相应的kernel设备,不然就卡死在“Uncompressing Linux… done, booting the kernel.”之后了。
boot时是如何匹配?
先看看arch/arm/include/asm/mach/arch.h 中的相关结构体
#define MACHINE_START(_type,_name) \ static const struct machine_desc __mach_desc_##_type \ __used \ __attribute__((__section__(".arch.info.init"))) = { \ .nr = MACH_TYPE_##_type, \ .name = _name, #define MACHINE_END
struct machine_desc { unsigned int nr; /* architecture number */ const char *name; /* architecture name */ ...
在看编译的设备文件arch/arm/mach-s3c24xx/mach-mini2440.c中最后的MACHINE_START定义
MACHINE_START(MINI2440, "MINI2440") /* Maintainer: Michel Pollet <buserror@gmail.com> */ .atag_offset = 0x100, .map_io = mini2440_map_io, .init_machine = mini2440_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, .restart = s3c244x_restart, MACHINE_END
可看到这里定义了一个machine_desc( __mach_desc_MINI2440 )
.nr=MACHINE_TYPE_MINI2440//本质就是机器码number
.name=”MINI2440”
内核启动时如下:
bootloader将机器码等参数传入–飞凌里的boot如下call_linux(0, machine id, runaddr)– kernel接收到后运行如下:start_kernel–> setup_arch(&command_line) –>setup_machine_tags(machine_arch_type)–>for_each_machine_desc(p)
//在所有编译进来的MACHIE中根据p->nr=machine_arch_type找出mdesc for_each_machine_desc(p) if (nr == p->nr) { printk("Machine: %s\n", p->name);//显示"MINI2440" mdesc = p; break; }
2.3 修改Kconfig和添加.c文件
依上面的添加项修改lxa2440 MACH_LXA2440 LXA2440
2.3.1 增加menuconfig配置项,主要修改 arch/arm/mach-s3c24xx/Kconfig
config MACH_LXA2440 bool "LXA2440 development board" select S3C_DEV_NAND select S3C_DEV_USB_HOST help Say Y here if you are using the LXA2440
2.3.2 在 arch/arm/mach-s3c24xx/Makefile中添加machine.c文件的编译控制配置
78 obj-$(CONFIG_MACH_LXA2440) += mach-lxa2440.o
2.3.3 关闭NAND_ECC校验
在drivers/mtd/nand/s3c2410.c文件内修改chip->ecc.mode = NAND_ECC_NONE; //旧的为NAND_ECC_SOFT
这是网上流传的方法 ,分析代码发现
if (set->disable_ecc) chip->ecc.mode = NAND_ECC_NONE;
只要set->disable_ecc为真就行,追踪下发现在mach-mini2440.c(就是我说的machine.c文件)的NAND分区设置里可以增加此参数,因此我用如下方法修改
static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = { [0] = { .name = "nand", .nr_chips = 1, .nr_partitions = ARRAY_SIZE(mini2440_default_nand_part), .partitions = mini2440_default_nand_part, .flash_bbt = 1, /* we use u-boot to create a BBT */ .disable_ecc =1,//增加此参数就行 }, };
成功后启动会出现
s3c24xx-nand s3c2440-nand: NAND ECC disabled字样
2.3.4 添加machine.c源码
用mach-mini2440或mach-smdk2440为模版修改- 修改machine名字,不改也行,只要将
MACHINE_START(LXA2440, "LXA2440")这句改好就行了。
``` cd arch/arm/mach-s3c24xx/ cp mach-mini2440.c mach-lxa2440.c vi mach-lxa2440.c ``` ``` :%s/MINI/LXA/g :%s/mini/lxa/g ```
- 检查时钟频率:s3c24xx_init_clocks(12000000);
- 依bootloader修改NAND分区
``` static struct mtd_partition lxa2440_default_nand_part[] __initdata = { [0] = { .name = "Boot", .size = 0x01000000, .offset = 0, }, [1] = { .name = "MyApp", .size = 0x003c0000, .offset = 0x00140000, }, [2] = { .name = "Kernel", .size = 0x00300000, .offset = 0x00500000, }, [3] = { .name = "fs_yaffs", .offset = 0x00800000, .size = 0x03c00000, }, [4] = { .name = "WINCE", .offset = 0x04400000, .size = 0x03c00000, } }; ```
添加LCD配置,我用的是4.3寸屏
在static struct s3c2410fb_display lxa2440_lcd_cfg[] 末加入新增配置如下
[4] = { .type = (S3C2410_LCDCON1_TFT | S3C2410_LCDCON1_TFT24BPP), .width = 480, .height = 272, .pixclock = 40000, /*这个不会算,所以就直接一个个填了没用宏定义 */ .xres = 480, .yres = 272, .bpp = 32, .left_margin = 2, .right_margin = 2, .hsync_len = 41, .upper_margin = 2, .lower_margin = 2, .vsync_len = 10, .lcdcon5 = (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_HWSWP | S3C2410_LCDCON5_PWREN), },
然后修改lxa2440_features_str变量
/* * lxa2440_features string * * t = Touchscreen present * b = backlight control * c = camera [TODO] * 0-9 LCD configuration * */ static char lxa2440_features_str[12] __initdata = "4t";
由下面的代码也可知,也可以通过bootloader的启动参数设置(lxa2440=4),
static int __init lxa2440_features_setup(char *str) { if (str) strlcpy(lxa2440_features_str, str, sizeof(lxa2440_features_str)); return 1; } __setup("lxa2440=", lxa2440_features_setup);//由__setup定义都可以通过command line传递参数
添加触摸设备
添加头文件:#include < plat/ts.h > //新片内核以更改了位置
添加s3c2410_ts_mach_info结构
static struct s3c2410_ts_mach_info lxa2440_ts_info = { .delay = 10000, //延时 .presc = 49, //预分频 .oversampling_shift = 2,//采样次数 2的2次方 };
在初始化
lxa2440_init(void)中初始化触摸设备
s3c24xx_ts_set_platdata(&lxa2440_ts_info);
修改
lxa2440_parse_features中的case ‘t’,添加触摸设备s3c_device_ts,
case 't': if(features->done & FEATURE_TOUCH) printk(KERN_INFO "LXA2440: '%c' ignored, " "touchscreen not compiled in\n", f); else { features->optional[features->count++] = &s3c_device_ts; } features->done |= FEATURE_TOUCH; break;
在
static struct platform_device *lxa2440_devices[]中添加adc设备
&s3c_device_adc
三、make menuconfig 配置内核
3.1首先更改System Type,选中我们添加的LXA2440设备System Type –>SAMSUNG S3C24XX SoCs Support —> S3C2440 Boards –>[*] LXA2440 development board,勾除MINI2440
3.2 更改下Kernel Features ,勾上
[*] Provide old way to pass kernel parameters //不同版本位置稍有区别,4.0.0之后的版本好像是在boot option里
因为飞凌的bootloader版本旧,不兼容会导致卡死在Uncompressing 那里。具体分析可看我另一篇 基于FL2440的3.6.6内核移植出现Uncompressing Linux… done, booting the kernel.
添加 触摸驱动
Device Drivers->Input device support —> [] Touchscreens —> <> Samsung S3C2410/generic touchscreen input driver
退出保存
四、编译下载
make clean make zImage
本方法同样适用于4.4.16 ,在4.5.4版本中移植网络有问题,无法NFS启动.照理说只有添加网卡平台设备就行了,可怎么也link up 不了,
五、参考文章
3.1 本移植记录是参考基于S3C2440的linux-3.6.6移植——内核移植,建立自己的平台系统,在此感谢3.2 kernel内核中处理器类型的定义mach-types.h文件的生成
相关文章推荐
- Day One 水题
- 对象和数组的深浅拷贝
- Debug---Eclipse断点调试基础
- NYOJ 快速查找素数问题(筛法)
- iOS 图片加载导致内存警告
- 线上mongodb 数据库用户到期时间修改的操作记录
- C++问题,对象包含与成员函数不兼容的类型限定符
- 深入理解Java:注解(Annotation)--注解处理器
- BSON与JSON的区别
- SolrCloud之Sharding路由介绍
- vim使用技巧篇
- PREROUTING 和 POSTROUTING, SNAT 和 DNAT图文解析(非常清淅)
- 知乎上关于游戏引擎的讨论
- Xdebug+PhpStorm
- 字符串反转
- 字符串的全排列和组合问题整理
- 多线程断点续传(一)
- DenseCap解读
- sort冒泡
- C++策略模式