您的位置:首页 > 其它

基于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 配置内核

四编译下载

五参考文章

一、前期准备工作

成功启动的提示信息,可以看出我的编译环境

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文件的生成
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: