下面开始正题
注:内核启动时可能会出现乱码,可以在u-boot下设置如下环境变量:setenv bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200
saveenv
1.1下载Linux3.19的源代码
从Linux kernel的官方网站可以下载最新的内核代码,我们选择linux-3.19.4.tar.gz这个文件下载。下载后解压至工作目录。进入内核目录,打开Makefile文件,修改如下两行:
-ARCH ?= $(SUBARCH)
-CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
+ARCH ?= $(SUBARCH)
+CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
保存退出后执行
root@ginger-virtual-machine:/home/ginger/mini2440/linux-3.19.3# make menuconfig
打开内核配置界面,不做任何操作直接退出,然后在终端执行
root@ginger-virtual-machine:/home/ginger/mini2440/linux-3.19.3# make mini2440_defconfig显示
## configuration written to .config
#
说明已经对采用了内核自带的mini2440的配置,这样可以减少我们手动配置内核的工作量。此时我们执行
root@ginger-virtual-machine:/home/ginger/mini2440/linux-3.19.3# make zImage
发现已经可以编译内核并生成内核镜像,这是因为新版本的Linux内核已经添加了对mini2440的支持.
1.2添加对平台的支持
在/linux-3.19.3/arch/arm/mach-s3c24xx目录下有一个名为mach-mini2440.c的源文件, 但是我们不使用它,将其删除后将该目录下的mach-smdk2440.c文件复制一份并改名为mach-mini2440.c.打开mach-mini2440.c文件,将其中关于LCD的定义均删除,后续我们将自己添加LCD驱动相关代码。
/* LCD driver info */
static struct s3c2410fb_display smdk2440_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 smdk2440_fb_info __initdata = {
.displays = &smdk2440_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,
};
同时将static struct platform_device *mini2440_devices[] __initdata 函数中的&s3c_device_lcd,注释,将static void __init mini2440_machine_init(void)函数中的s3c24xx_fb_set_platdata(&mini2440_fb_info)和smdk_machine_init();注释。然后使用替换功能将代码中的所有smdk2440均替换为mini2440.
1.3修改晶振频率
将static void __init mini2440_init_time(void)函数中的s3c2440_init_clocks(16934400);更改为s3c2440_init_clocks(12000000)
1.4找到MACHINE_START(S3C2440, "SMDK2440")函数,将其修改为MACHINE_START(MINI2440, "Ginger's board"),如果不修改,将导致内核启动时直接卡在Starting kernel .......................处。此时保存后编译,内核已可以正常编译,但此时还有大部分驱动未编写,内核还无法正常启动。下一步我们将在源码中增加关于nand flash分区表的相关内容
1.5添加nand flash的支持
在mach-mini2440.c中增加以下内容
/* 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 = 0,
.twrph0 = 25,
.twrph1 = 15,
.nr_sets = ARRAY_SIZE(mini2440_nand_sets),
.sets = mini2440_nand_sets,
.ignore_unset_ecc = 1,
};
添加如下头文件
#include#include
#include
#include
#include
在static struct platform_device *mini2440_devices[] __initdata函数中增加&s3c_device_nand,在static void __init mini2440_machine_init(void)函数中增加s3c_nand_set_platdata(&mini2440_nand_info);
保存后编译,下载到开发板上,可看到如下启动信息:
s3c24xx-nand s3c2440-nand: Tacls=1, 9ns Twrph0=3 29ns, Twrph1=2 19nss3c24xx-nand s3c2440-nand: NAND soft ECC
nand: device found, Manufacturer ID: 0xec, Chip ID: 0xda
nand: Samsung NAND 256MiB 3,3V 8-bit
nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
Creating 5 MTD partitions on "nand":
0x000000000000-0x000000040000 : "supervivi"
__nand_correct_data: uncorrectable ECC error
0x000000040000-0x000000060000 : "param"
ftl_cs: FTL header not found.
0x000000060000-0x000000560000 : "Kernel"
ftl_cs: FTL header not found.
0x000000560000-0x000040560000 : "root"
mtd: partition "root" extends beyond the end of device "nand" -- size truncated to 0xfaa0000
ftl_cs: FTL header not found.
0x000000000000-0x000040000000 : "nand"
mtd: partition "nand" extends beyond the end of device "nand" -- size truncated to 0x10000000
__nand_correct_data: uncorrectable ECC error
发现开发板已经可以识别nand flash的信息,但是打印出如下信息:
ftl_cs: FTL header not found.
解决方法如下:在内核根目录下执行make menuconfig,进入
Device Drivers ->
Memory Technology Devices (MTD) ->
去掉如下选项
<>FTL (Flash Translation Layer) support
<> NFTL (NAND Flash Translation Layer) support
<>INFTL (Inverse NAND Flash Translation Layer) support
保存后重新编译即可。
1.6到目前为止已经完成了对nand flash的支持,但是因为缺少根文件系统,内核依旧无法正常启动。接下去我们将为内核添加对yaffs2的支持。
在终端下执行#git clone git://www.aleph1.co.uk/yaffs2 获取最新的yaffs2源码。同步完后,进入yaffs2目录,执行# ./patch-ker.sh c m 内核源码路径,既可对内核打上yaffs2的补丁。进入内核目录,执行make menuconfig
选择File systems --->
[*] Miscellaneous filesystems --->
│ <*> yaffs2 file system support
保存后退出,重新编译,此时会遇到几个错误,因为新版的Linux内核有一些对文件操作的函数进行了修改,我们需要按照错误逐一进行修改。按照错误:
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_readpage_nolock':
fs/yaffs2/yaffs_vfs.c:286: error: 'struct file' has no member named 'f_dentry'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_hold_space':
fs/yaffs2/yaffs_vfs.c:484: error: 'struct file' has no member named 'f_dentry'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_release_space':
fs/yaffs2/yaffs_vfs.c:502: error: 'struct file' has no member named 'f_dentry'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_file_write':
fs/yaffs2/yaffs_vfs.c:594: error: 'struct file' has no member named 'f_dentry'
fs/yaffs2/yaffs_vfs.c:606: error: 'struct file' has no member named 'f_dentry'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_file_flush':
fs/yaffs2/yaffs_vfs.c:730: error: 'struct file' has no member named 'f_dentry'
fs/yaffs2/yaffs_vfs.c:741: error: too few arguments to function 'yaffs_flush_file'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_sync_object':
fs/yaffs2/yaffs_vfs.c:771: error: too few arguments to function 'yaffs_flush_file'
fs/yaffs2/yaffs_vfs.c: At top level:
fs/yaffs2/yaffs_vfs.c:781: error: 'generic_file_aio_read' undeclared here (not in a function)
fs/yaffs2/yaffs_vfs.c:782: error: 'generic_file_aio_write' undeclared here (not in a function)
fs/yaffs2/yaffs_vfs.c:787: error: 'generic_file_splice_write' undeclared here (not in a function)
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_iterate':
fs/yaffs2/yaffs_vfs.c:1719: error: 'struct file' has no member named 'f_dentry'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_flush_inodes':
fs/yaffs2/yaffs_vfs.c:2190: error: too few arguments to function 'yaffs_flush_file'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_flush_super':
fs/yaffs2/yaffs_vfs.c:2203: error: too few arguments to function 'yaffs_flush_whole_cache'
打开/fs/yaffs2/yaffs_vfs.c,使用替换功能,将代码中的所有f_dentry均替换为f_path.dentry,将所有的yaffs_flush_file(obj, 1, 0);替换为yaffs_flush_file(obj, 1, 0,1);将yaffs_flush_file(obj, 1, datasync);替换为yaffs_flush_file(obj, 1, datasync,1);将yaffs_flush_file(obj, 1, 0);替换为yaffs_flush_file(obj, 1, 0,1);yaffs_flush_whole_cache(dev);替换为yaffs_flush_whole_cache(dev,1);
718行附近
- .read = do_sync_read,
- .write = do_sync_write,
+ .read = new_sync_read,
+ .write = new_sync_write,
- .aio_read = generic_file_aio_read,
- .aio_write = generic_file_aio_write,
+ .read_iter = generic_file_read_iter,
+ .write_iter = generic_file_write_iter,
- .splice_write = generic_file_splice_write,
+ .splice_write = iter_file_splice_write,
保存后重新编译,下载内核至开发板,同时烧录文件系统(为了测试方便,这次我先使用友善提供的制作好的文件系统root_qtopia.img在以后的教程中我们也会制作自己的文件系统),重启开发板,看到如下引导信息
Starting kernel ...
Booting Linux on physical CPU 0x0
Linux version 3.19.3 (root@ginger-virtual-machine) (gcc version 4.4.3 (ctng-1.6.1) ) #6 Sat Apr 25 13:37:14 CST 2015
上一篇:对mini2440存储器的理解和使用
下一篇:mini2440采用minitools工具烧写系统或裸机程序方法
推荐阅读最新更新时间:2024-11-12 13:50