本人大二在校生一枚,最近开始接触嵌入式Linux系统,跟着友善提供的Linux移植手册操作了一遍后决定自己移植一个当前较新的内核(3.19)作为练习,为了避免日后遗忘,同时也是作为学习的一个记录,决定在此将整个移植的过程进行详细的记录。因为自己也是个新手,难免会有许多错误,还请读者能够指出。
下面开始正题
注:内核启动时可能会出现乱码,可以在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 19ns
s3c24xx-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
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 --->
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'
- .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,
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
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c000717f
CPU: VIVT data cache, VIVT instruction cache
Machine: Ginger's board
Memory policy: Data cache writeback
CPU S3C2440A (id 0x32440001)
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 59192K/65536K available (4003K kernel code, 193K rwdata, 1072K rodata, 160K init, 246K bss, 6344K reserved, 0K cma-reserved)
Virtual kernel memory layout:
vector : 0xffff0000 - 0xffff1000 ( 4 kB)
fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
vmalloc : 0xc4800000 - 0xff000000 ( 936 MB)
lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)
modules : 0xbf000000 - 0xc0000000 ( 16 MB)
.text : 0xc0008000 - 0xc04fd0a0 (5077 kB)
.init : 0xc04fe000 - 0xc0526000 ( 160 kB)
.data : 0xc0526000 - 0xc0556640 ( 194 kB)
.bss : 0xc0556640 - 0xc0594098 ( 247 kB)
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:103
S3C2440: IRQ Support
irq: clearing pending status 00000002
sched_clock: 16 bits at 1012kHz, resolution 987ns, wraps every 64725925ns
Console: colour dummy device 80x30
Calibrating delay loop... 201.52 BogoMIPS (lpj=503808)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x303d2488 - 0x303d24e0
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
cpuidle: using governor ladder
cpuidle: using governor menu
S3C2440: Initialising architecture
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
s3c-i2c s3c2440-i2c.0: slave address 0x10
s3c-i2c s3c2440-i2c.0: bus frequency set to 98 KHz
s3c-i2c s3c2440-i2c.0: i2c-0: S3C I2C adapter
Advanced Linux Sound Architecture Driver Initialized.
Switched to clocksource samsung_clocksource_timer
NET: Registered protocol family 2
TCP established hash table entries: 1024 (order: 0, 4096 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP: reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
futex hash table entries: 256 (order: -1, 3072 bytes)
NFS: Registering the id_resolver key type
Key type id_resolver registered
Key type id_legacy registered
jffs2: version 2.2. (NAND) 漏 2001-2006 Red Hat, Inc.
romfs: ROMFS MTD (C) 2007 Red Hat, Inc.
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
s3c2440-uart.0: ttySAC0 at MMIO 0x50000000 (irq = 74, base_baud = 0) is a S3C2440
console [ttySAC0] enabled
s3c2440-uart.1: ttySAC1 at MMIO 0x50004000 (irq = 77, base_baud = 0) is a S3C2440
s3c2440-uart.2: ttySAC2 at MMIO 0x50008000 (irq = 80, base_baud = 0) is a S3C2440
brd: module loaded
s3c24xx-nand s3c2440-nand: Tacls=1, 9ns Twrph0=3 29ns, Twrph1=2 19ns
s3c24xx-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"
0x000000040000-0x000000060000 : "param"
0x000000060000-0x000000560000 : "Kernel"
0x000000560000-0x000040560000 : "root"
mtd: partition "root" extends beyond the end of device "nand" -- size truncated to 0xfaa0000
0x000000000000-0x000040000000 : "nand"
mtd: partition "nand" extends beyond the end of device "nand" -- size truncated to 0x10000000
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-s3c2410: OHCI S3C2410 driver
s3c2410-ohci s3c2410-ohci: OHCI Host Controller
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq disabled
Driver 'mmcblk' needs updating - please use bus_type methods
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
hidraw: raw HID events driver (C) Jiri Kosina
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
TCP: cubic registered
NET: Registered protocol family 17
Key type dns_resolver registered
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
ALSA device list:
No soundcards found.
yaffs: dev is 32505859 name is "mtdblock3" rw
yaffs: passed flags ""
VFS: Mounted root (yaffs filesystem) on device 31:3.
Freeing unused kernel memory: 160K (c04fe000 - c0526000)
mount: mounting none on /proc/bus/usb failed: No such file or directory
hwclock: can't open '/dev/misc/rtc': No such file or directory
[01/Jan/1970:00:00:07 +0000] boa: server version Boa/0.94.13
[01/Jan/1970:00:00:07 +0000] boa: server built Mar 26 2009 at 15:28:42.
[01/Jan/1970:00:00:07 +0000] boa: starting server pid=784, port 80
open device leds: No such file or directory
Try to bring eth0 interface up......ifconfig: SIOCGIFFLAGS: No such device
ifconfig: SIOCSIFHWADDR: No such device
ifconfig: SIOCSIFADDR: No such device
route: SIOCADDRT: Network is unreachable
Done
Please press Enter to activate this console.
[root@FriendlyARM /]# cat /proc/version
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
相关文件