一、基本内核移植 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:www.neusoft.edu.cn:eth0:off 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] [<c0031fb8>] (dump_backtrace+0x0/0x110) from [<c0394684>] (dump_stack+0x18/0x1c) [ 2.797411] r6:efc2c000 r5:c0520818 r4:c051f084 r3:00000000 [ 2.797473] [<c039466c>] (dump_stack+0x0/0x1c) from [<c0394700>] (panic+0x78/0xf8) [ 2.804909] [<c0394688>] (panic+0x0/0xf8) from [<c0054b84>] (do_exit+0x74/0x5f0) [ 2.812257] r3:c0520818 r2:00000000 r1:efc2fe10 r0:c04a25e2 [ 2.817881] [<c0054b10>] (do_exit+0x0/0x5f0) from [<c0055198>] (do_group_exit+0x98/0xc8) [ 2.825961] [<c0055100>] (do_group_exit+0x0/0xc8) from [<c0060cec>] (get_signal_to_deliver+0x358/0x394) [ 2.835310] r7:efdd9a04 r6:efc2fec8 r5:00106001 r4:efc2e000 [ 2.840933] [<c0060994>] (get_signal_to_deliver+0x0/0x394) from [<c0030d00>] (do_signal+0x70/0x674) [ 2.849962] [<c0030c90>] (do_signal+0x0/0x674) from [<c0031324>] (do_notify_resume+0x20/0x50) [ 2.858455] [<c0031304>] (do_notify_resume+0x0/0x50) from [<c002e010>] (work_pending+0x1c/0x20) [ 2.867113] r4:ffffffff r3:000000005 |
|