目录
概述
1 配置编译环境
2 编译内核
2.1 配置内核
2.2 编译存在的问题
2.3 验证zImage
3 移植 yaffs2
3.1 下载yaffs2
3.2 为内核打上 yaffs2 补丁
3.3 配置和编译带 YAFFS2 支持的内核
3.3.1 配置 YAFFS2内核
3.3.2 编译带YAFFS2 支持的内核
3.4 验证带YAFFS2 支持的内核
4 问题汇总
4.1 存在问题1
4.1.1 问题log信息
4.1.2 解决方法:
4.2 存在问题2
4.2.1 问题log信息
4.2.2 解决方法
5 总结
概述
本文主要介绍移植移植内核linux-2.6.32.24遇见的问题和解决方法,使用的硬件系统为:mini2440,交叉编译器版本为:FriendlyARM提供的arm-linux-gcc-4.4.3.tar.gz。其他编译器没有试过,官方文档介绍,如果使用其他编译器,可能出现不能运行的情况。本文详细的记录了linux-2.6.32.24内核遇见的问题,并记录了解决这些问题的方法。
1 配置编译环境
linux内核的官方镜像地址:
https://mirrors.edge.kernel.org/pub/linux/kernel/
下载和解压内核后,修改内核根目录下/linux-2.6.32.24/Makefile文件中修改代码
代码183: 配置CPU架构为arm
代码184: 配置编译器路径,使用FriendlyARM提供的编译器版本
2 编译内核
2.1 配置内核
make clean
make mini2440_defconfig
2.2 编译存在的问题
问题描述:defined(@array) 这种语法,编译器不识别,需要更改成编译可识别的语法形式,更改方法见下文。
Error log 信息如下:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
make[1]: *** [/home/mftang/mini2440_study/kernel/linux-2.6.32.24/kernel/Makefile:129: kernel/timeconst.h] Error 255
找到出问题的地方,文件地址: linux-2.6.32.24/kernel/timeconst.pl
修改问题:
保存修改的代码,重新编译内核,执行命令
make zImage
已经生成zImage文件,编译内核成功。
2.3 验证zImage
下载zImage至MCU中,下载方法如下:
FriendlyARM提供了MiniTools工具,非常方便下载内核,下载完成内核后,拨动拨码开关至NAND Flash启动位置,linux系统会从Nandflash启动,log信息如下:
内核能够正确的被解压出来,并能正常启动。还存在如下问题:
No filesystem could mount root, tried: ext3 cramfs vfat msdos romfs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,3)
[<c002e8a0>] (unwind_backtrace+0x0/0xd8) from [<c02d5b64>] (panic+0x40/0x118)
[<c02d5b64>] (panic+0x40/0x118) from [<c0008e74>] (mount_block_root+0x1c8/0x208)
[<c0008e74>] (mount_block_root+0x1c8/0x208) from [<c0009108>] (prepare_namespace+0x160/0x1b8)
[<c0009108>] (prepare_namespace+0x160/0x1b8) from [<c0008434>] (kernel_init+0xd8/0x10c)
[<c0008434>] (kernel_init+0xd8/0x10c) from [<c002a868>] (kernel_thread_exit+0x0/0x8)
解决方法: 需要移植yaffs2
3 移植 yaffs2
3.1 下载yaffs2
登录下网址,看见如下页面
https://yaffs.net/get-yaffs
下载方法:
git clone git://www.aleph1.co.uk/yaffs2
执行命令后:
3.2 为内核打上 yaffs2 补丁
linux-2.6.32.24内核和yaffs2在同一个目录中。
进入到yaffs2,执行命令
cd yaffs2
./patch-ker.sh c /home/mftang/mini2440_study/kernel/linux-2.6.32.24
存在的问题:
问题log:
usage: ./patch-ker.sh c/l m/s kernelpath
if c/l is c, then copy. If l then link
if m/s is m, then use multi version code. If s then use single version code
解决方法:
./patch-ker.sh c m /home/mftang/mini2440_study/kernel/linux-2.6.32.24
执行命令后,看见如下log:
进入到/home/mftang/mini2440_study/kernel/linux-2.6.32.24/fs,查看yaffs2文件夹
3.3 配置和编译带 YAFFS2 支持的内核
3.3.1 配置 YAFFS2内核
执行命令 make menuconfig ,进入到配置页面
make menuconfig
step - 1: 跳到File system
step-2: 跳到Miscellaneous filesystems
step-3: 选中 YAFFS2 file system support , 退出配置页面
step-4: 使用Exit退出配置页面,完全退出后
3.3.2 编译带YAFFS2 支持的内核
执行命令make zImage,编译内核源码
make zImage
通过log信息,可以看见yaffs2已经被编译到内核中
3.4 验证带YAFFS2 支持的内核
使用工具MiniTools烧写内核到MCU
4 问题汇总
4.1 存在问题1
4.1.1 问题log信息
重启系统后,板卡打印如下log信息:
存在问题的log
log 信息如下:
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Creating 5 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x000000000000-0x000000040000 : "supervivi"
uncorrectable error :
0x000000040000-0x000000060000 : "param"
uncorrectable error :
0x000000060000-0x000000560000 : "Kernel"
uncorrectable error :
0x000000560000-0x000040560000 : "root"
mtd: partition "root" extends beyond the end of device "NAND 256MiB 3,3V 8-bit" -- size truncated to 0xfaa0000
ftl_cs: FTL header not found.
0x000000000000-0x000040000000 : "nand"
mtd: partition "nand" extends beyond the end of device "NAND 256MiB 3,3V 8-bit" -- size truncated to 0x10000000
uncorrectable error :
4.1.2 解决方法:
禁止和Nand flash相关的一些选项
step -1: 进入Devices Drivers
step -2: 进入到 Memory Technology Devices (MTD) support
step -3:在该页面禁止如下3个选项
step -4: 保存退出,重新编译内核
step - 5: 下载内核和验证,问题已经解决
4.2 存在问题2
4.2.1 问题log信息
问题log:
last sysfs file:
Modules linked in:
CPU: 0 Not tainted (2.6.32.24 #5)
PC is at 0x2f20702c
LR is at s3c2410_nand_select_chip+0x88/0xa0
pc : [<2f20702c>] lr : [<c01ea1a8>] psr: 20000033
sp : c38239a8 ip : 00000004 fp : 00000000
r10: 00000001 r9 : 00002925 r8 : 00000000
r7 : 019f2800 r6 : 00000003 r5 : c39b2700 r4 : 00000000
r3 : 2f20702d r2 : c4c00004 r1 : 00000000 r0 : c0025648
Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user
Control: c000717f Table: 33a48000 DAC: 00000015
Process linuxrc (pid: 1, stack limit = 0xc3822270)
Stack: (0xc38239a8 to 0xc3824000)
4.2.2 解决方法
重写/linux-2.6.32.24/arch/arm/mach-s3c2440/mach-mini2440.c这个文件,修改后的代码如下:
/***********************************************************
Copyright 2024-2029. All rights reserved.
文件名 : linux/arch/arm/mach-s3c2440/mach-mini2440.c
作者 : tangmingfei2013@126.com
版本 : V1.0
描述 : mini2440板卡驱动程序
其他 : 无
日志 : 初版V1.0 2024/3/19
***********************************************************/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-lcd.h>
#include <mach/idle.h>
#include <mach/fb.h>
#include <plat/iic.h>
#include <plat/s3c2410.h>
#include <plat/s3c2440.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/nand.h>
#include <plat/pm.h>
#include <plat/mci.h>
#include <plat/common-smdk.h>
static struct map_desc mini2440_iodesc[] __initdata = {
/* ISA IO Space map (memory space selected by A24) */
{
.virtual = (u32)S3C24XX_VA_ISA_WORD,
.pfn = __phys_to_pfn(S3C2410_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE,
.pfn = __phys_to_pfn(S3C2410_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
}
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
/* IR port */
[2] = {
.hwport = 2,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x43,
.ufcon = 0x51,
}
};
/* LCD driver info */
static struct s3c2410fb_display mini2440_lcd_cfg __initdata = {
.lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_PWREN |
S3C2410_LCDCON5_HWSWP,
.type = S3C2410_LCDCON1_TFT,
.width = 240,
.height = 320,
.pixclock = 166667, /* HCLK 60 MHz, divisor 10 */
.xres = 240,
.yres = 320,
.bpp = 16,
.left_margin = 20,
.right_margin = 8,
.hsync_len = 4,
.upper_margin = 8,
.lower_margin = 7,
.vsync_len = 4,
};
static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
.displays = &mini2440_lcd_cfg,
.num_displays = 1,
.default_display = 0,
#if 0
/* currently setup by downloader */
.gpccon = 0xaa940659,
.gpccon_mask = 0xffffffff,
.gpcup = 0x0000ffff,
.gpcup_mask = 0xffffffff,
.gpdcon = 0xaa84aaa0,
.gpdcon_mask = 0xffffffff,
.gpdup = 0x0000faff,
.gpdup_mask = 0xffffffff,
#endif
.lpcsel = ((0xCE6) & ~7) | 1<<4,
};
/* NAND Flash on MINI2440 board */
static struct mtd_partition mini2440_default_nand_part[] = {
[0] = {
.name = "supervivi",
.size = 0x00040000,
.offset = 0,
},
[1] = {
.name = "param",
.offset = 0x00040000,
.size = 0x00020000,
},
[2] = {
.name = "Kernel",
.offset = 0x00060000,
.size = 0x00500000,
},
[3] = {
.name = "root",
.offset = 0x00560000,
.size = 1024 * 1024 * 1024,
},
[4] = {
.name = "nand",
.offset = 0x00000000,
.size = 1024 * 1024 * 1024,
}
};
static struct s3c2410_nand_set mini2440_nand_sets[] = {
[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 */
},
};
static struct s3c2410_platform_nand mini2440_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(mini2440_nand_sets),
.sets = mini2440_nand_sets,
.ignore_unset_ecc = 1,
};
static struct platform_device *mini2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_nand,
};
static void __init mini2440_map_io(void)
{
s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
}
static void __init mini2440_machine_init(void)
{
#if defined (LCD_WIDTH)
s3c24xx_fb_set_platdata(&mini2440_fb_info);
#endif
s3c_i2c0_set_platdata(NULL);
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
//smdk_machine_init();
s3c_device_nand.dev.platform_data = &mini2440_nand_info;
}
MACHINE_START(MINI2440, "MFTANG_MINI2440")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
修改完成后,重新编译内核,并下载到板卡中,然后重启板卡,运行的log如下:
出现如下log,说明内核已经启动了,并且挂载了rootfs文件系统,控制台也能正常登录和操作了。
5 总结
内核中提供的mach-mini2440.c的驱动程序还是有问题的,具体什么问题,笔者还没有详细分析过。移植新的内核,还是必须参看FriendARM提供的文档一步步操作,重新编写mach-mini2440.c文件,这样才能保证内核能够被正确的移植。