分类: 嵌入式
2014-01-29 22:43:51
一、基本内核移植
1. 解压内核源码包
tar jxvf android_kernel_2.6.35_smdkv210.tar.bz2
cd android-kernel-samsung-dev/
2. 修改Makefile中的体系结构ARCH和交叉编译器前缀CROSS_COMPILE
vim Makefile
修改191和192行为如下:
ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
3. 使用SMDKV210的缺省配置文件
make smdkv210_android_defconfig
4. 配置内核,修改串口
make menuconfig
修改底层消息和底层调试串行端口为UART0:
System Type --->
(0) S3C UART to use for low-level messages
Kernel hacking --->
(0) S3C UART to use for low-level debug
5. 确定机器码
vim arch/arm/tools/mach-types
在433行可以看出,SMDKV210评估板的机器码是2456(16进制是0x998):
smdkv210 MACH_SMDKV210 SMDKV210 2456
6. 确定内核的加载地址和参数地址
vim arch/arm/mach-s5pv210/Makefile.boot
可以看出,内核的加载地址和参数地址分别为0x20008000和0x20000100,bootloader启动内核前应该将内核拷贝到0x20008000,并将参数放到0x20000100。
zreladdr-y += 0x20008000
params_phys-y := 0x20000100
7. 编译内核
make uImage -j 2
-j 2指定了编译时的线程数,使用2个线程可加快编译的速度,编译完成后可以看到:
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gzip
AS arch/arm/boot/compressed/piggy.gzip.o
CC arch/arm/boot/compressed/misc.o
CC arch/arm/boot/compressed/decompress.o
SHIPPED arch/arm/boot/compressed/lib1funcs.S
AS arch/arm/boot/compressed/lib1funcs.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-2.6.35.7
Created: Mon Mar 4 17:18:54 2013
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2667648 Bytes = 2605.12 kB = 2.54 MB
Load Address: 20008000
Entry Point: 20008000
Image arch/arm/boot/uImage is ready
可以看出,内核的加载地址的确是0x20008000,进入点地址也是0x20008000,u-boot支持的Linux内核映像uImage也可用了,它在arch/arm/boot目录。
在编译Linux内核,配置时:
make menuconfig ---> Kernel hacking --> show timing information on printks
当选中这个选项后,启动内核,会在日志信息前面加上时间戳。从下面的输出可以看出,时间精确到微秒(us)。如下:
8. 设置u-boot的环境变量
现在我们需要在u-boot下设置一些环境变量,其中bootargs是引导参数行,machid是机器码,0x998即2456,即SMDKV210评估板,最后输入saveenv保存环境变量到Nand Flash:
SMDKV210 # setenv bootargs root=/dev/nfs nfsroot=192.168.0.5:/work/rootfile/rootfs ip=192.168.0.1:192.168.0.5:192.168.0.1:255.255.255.0: console=ttySAC0
SMDKV210 # setenv machid 0x998
SMDKV210 # saveenv
Saving Environment to SMDK bootable device...
Erasing Nand...
Writing to Nand...
Saved enviroment variables
在u-boot下输入bdinfo可以查看一些开发板的信息,可以看到boot_params引导参数的地址是0x20000100,这个地址和arch/arm/mach-s5pv210/Makefile.boot中的params_phys-y的值是一致的。内存DRAM分了两个BANK,其中DRAM 1的基地址是0x40000000,大小是0x10000000(即256MB):
SMDKV210 # bdinfo
arch_number = 0x00000998
env_t = 0x00000000
boot_params = 0x20000100
DRAM bank = 0x00000000
-> start = 0x20000000
-> size = 0x10000000
DRAM bank = 0x00000001
-> start = 0x40000000
-> size = 0x10000000
ethaddr = 00:40:5C:26:0A:5B
ip_addr = 192.168.0.20
baudrate = 115200 bps
9. 下载内核
由于u-boot并没有用到DRAM 1,所以DRAM 1可供我们暂存数据,在u-boot里通过TFTP下载内核映像uImage到DRAM 1的起始地址0x40000000:
SMDKV210 # tftp 0x40000000 uImage
10. 引导内核
从0x40000000地址处引导内核映像uImage:
SMDKV210 # bootm 0x40000000
get_format
-------- 1 --------
## Booting kernel from Legacy Image at 40000000 ...
Image Name: Linux-2.6.35.7
Created: 2013-03-05 1:18:54 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2667648 Bytes = 2.5 MB
Load Address: 20008000
Entry Point: 20008000
Verifying Checksum ... OK
get_format
-------- 1 --------
Loading Kernel Image ... OK
OK
Using machid 0x998 from environment
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 2.6.35.7 (root@localhost.localdomain) (gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67) ) #1 PREEMPT Mon Mar 4 17:18:30 PST 2013
[ 0.000000] CPU: ARMv7 Processor [412fc082] revision 2 (ARMv7), cr=10c53c7f
[ 0.000000] CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[ 0.000000] Machine: SMDKV210
。。。。。。省略部分。。。。。。
[ 0.000000] Kernel command line: console=ttySAC0,115200 root=/dev/mtdblock4 rootfstype=yaffs rw
[ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Memory: 256MB 256MB = 512MB total
[ 0.000000] Memory: 352128k/352128k available, 172160k reserved, 0K highmem
[ 0.000000] Virtual kernel memory layout:
。。。。。。省略部分。。。。。。
[ 0.670485] machine_constraints_voltage: failed to apply 1100000uV constraint to VALIVE_1.1V
[ 0.678443] Unable to handle kernel NULL pointer dereference at virtual address 00000060
[ 0.686442] pgd = c0004000
[ 0.689125] [00000060] *pgd=00000000
[ 0.692673] Internal error: Oops: 5 [#1] PREEMPT
[ 0.697262] last sysfs file:
[ 0.700209] Modules linked in:
[ 0.703245] CPU: 0 Not tainted (2.6.35.7 #1)
[ 0.707843] PC is at dev_driver_string+0xc/0x44
[ 0.712346] LR is at max8698_pmic_probe+0x150/0x32c
11. 引导结果分析
成功地启动了机器SMDKV210,说明机器码的传入是没有问题的,另外输出了“Kernel command line: console=ttySAC0,115200 root=/dev/mtdblock4 rootfstype=yaffs rw”,说明引导参数的传入也是没有问题的,虽然GEC210开发板不像SMDKV210开发板那样拥有512MB*2=1GB的内存,但内核通过u-boot传递进来的引导参数识别出256MB*2=512MB的内存,所以能输出“Memory: 256MB 256MB = 512MB total”这样的字符串。“Unable to handle kernel NULL pointer dereference at virtual address 00000060”提示了我们内核访问了不合法的虚拟地址,我们知道PC是当前程序计数寄存器,在正在运行的函数里,LR是链接地址寄存器,在调用者函数里,所以内核是在max8698电源管理芯片的探测函数max8698_pmic_probe里调用dev_driver_string函数时崩溃掉的,在移植u-boot时,我们把电源管理芯片的初始化函数屏蔽掉了,现在移植内核,同样要把max8698电源管理芯片的驱动去掉:
配置内核:
make menuconfig
去掉Maxim Semiconductor MAX8698 PMIC和Maxim 8698 voltage regulator的支持:
Device Drivers --->
[*] Multifunction device drivers --->
[ ] Maxim Semiconductor MAX8698 PMIC Support
[*] Voltage and Current Regulator Support --->
< > Maxim 8698 voltage regulator
重新编译内核:
make uImage -j 2
重新下载和引导内核:
[ 1.628906] yaffs: dev is 32505860 name is "mtdblock4" rw
[ 1.631831] yaffs: passed flags ""
[ 2.402354] VFS: Mounted root (yaffs filesystem) on device 31:4.
[ 2.402441] Freeing init memory: 148K
[ 2.797235] Kernel panic - not syncing: Attempted to kill init!
[ 2.797290] Backtrace:
[ 2.797339] [
[ 2.797411] r6:efc2c000 r5:c0520818 r4:c051f084 r3:00000000
[ 2.797473] [
[ 2.804909] [
[ 2.812257] r3:c0520818 r2:00000000 r1:efc2fe10 r0:c04a25e2
[ 2.817881] [
[ 2.825961] [
[ 2.835310] r7:efdd9a04 r6:efc2fec8 r5:00106001 r4:efc2e000
[ 2.840933] [
[ 2.849962] [
[ 2.858455] [
[ 2.867113] r4:ffffffff r3:000000005