本文主要探讨210官方kernel移植。
配置文件选择
选择配置文件smdkv210_android_defconfig(arch/arm/configs)
修改主Makefile
配置cpu架构和交叉编译工具链
vim MakefileARCH ?= armCROSS_COMPILE ?= /root/arm-2009q3/bin/arm-none-linux-gnueabi-
初步编译烧录
ubuntu:make smdkv210_android_defconfigmake -j4cp -r arch/arm/boot/zImage ~/tftp/uboot:tftp 30008000 zImagebootm 30008000
结果显示(无法启动):
一阶段移植(head.s)
初步移植未有kernel信息打印则说明一阶段(汇编)异常
led调试一阶段,添加led熄灭代码逐步测试(初始led亮)
led亮且未显示解压zImage信息则解压部分异常(实际为物理地址错误)
vim arch/arm/kernel/head.s/** Kernel startup entry point.* ---------------------------** This is normally called from the decompressor code. The requirements* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,* r1 = machine nr, r2 = atags pointer.** This code is mostly position independent, so if you link the kernel at* 0xc0008000, you call this at __pa(0xc0008000).** See linux/arch/arm/tools/mach-types for the complete list of machine* numbers for r1.** We're trying to keep crap to a minimum; DO NOT add any machine specific* crap here - that's what the boot loader (or in extreme, well justified* circumstances, zImage) is for.*/__HEAD
ENTRY(stext)setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode//test bl led_off@ and irqs disabledmrc p15, 0, r9, c0, c0 @ get processor idbl __lookup_processor_type @ r5=procinfo r9=cpuidmovs r10, r5 @ invalid processor (r5=0)?beq __error_p @ yes, error 'p'bl __lookup_machine_type @ r5=machinfomovs r8, r5 @ invalid machine (r5=0)?beq __error_a @ yes, error 'a'bl __vet_atagsbl __create_page_tables/** The following calls CPU specific code in a position independent* manner. See arch/arm/mm/proc-*.S for details. r10 = base of* xxx_proc_info structure selected by __lookup_machine_type* above. On return, the CPU will be ready for the MMU to be* turned on, and r0 will hold the CPU control register value.*/ldr r13, __switch_data @ address to jump to after@ mmu has been enabledadr lr, BSYM(__enable_mmu) @ return (PIC) addressARM( add pc, r10, #PROCINFO_INITFUNC )THUMB( add r12, r10, #PROCINFO_INITFUNC )THUMB( mov pc, r12 )
ENDPROC(stext)//led offled_off:ldr r3, =0x11111111ldr r4, = 0xE0200240str r3, [r4]ldr r3, =0xffldr r4, =0xE0200244str r3, [r4]mov pc, lr
修改物理地址
#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)(arch/arm/include/asm/memory.h)#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
(.config)CONFIG_PAGE_OFFSET=0xC0000000修改为(arch/arm/mach-s5pv210/include/mach/memory.h)
#if defined(CONFIG_MACH_SMDKV210)
#define PHYS_OFFSET UL(0x30000000)
#else
#define PHYS_OFFSET UL(0x30000000)
#endif
修改解压地址
vim arch/arm/mach-spv210/Makefile.boot# override for SMDKV210
zreladdr-$(CONFIG_MACH_SMDKV210) := 0x30008000
params_phys-$(CONFIG_MACH_SMDKV210) := 0x30000100
内核机器码确定分析
MACHINE_START宏定义机器码数据结构(硬件信息及其相关初始化函数等)
每个mach-xxx.c文件定义一个机器码machine_desc结构体变量且结构体变量被定义到段(.arch.info.init)
(arch/arm/mach-s5pv210/s5pc110.c)#ifdef CONFIG_MACH_SMDKC110MACHINE_START(SMDKC110, "SMDKC110")#elif CONFIG_MACH_SMDKV210MACHINE_START(SMDKV210, "SMDKV210")#endif/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */.phys_io = S3C_PA_UART & 0xfff00000,.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,.boot_params = S5P_PA_SDRAM + 0x100,.init_irq = s5pv210_init_irq,.map_io = smdkc110_map_io,.init_machine = smdkc110_machine_init,.timer = &s5p_systimer,MACHINE_END(.config)CONFIG_MACH_SMDKV210=y# CONFIG_MACH_SMDKC110 is not set(arch/arm/include/asm/mach/arch.h)#define MACHINE_START(_type,_name) \static const struct machine_desc __mach_desc_##_type \__used \__attribute__((__section__(".arch.info.init"))) = { \.nr = MACH_TYPE_##_type, \.name = _name,#define MACHINE_END \
};推导出():
static const struct machine_desc __mach_desc_SMDKV210 \__used \__attribute__((__section__(".arch.info.init"))) = { \.nr = MACH_TYPE_SMDKV210, \.name = "SMDKV210",.phys_io = S3C_PA_UART & 0xfff00000,.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,.boot_params = S5P_PA_SDRAM + 0x100,.init_irq = s5pv210_init_irq,.map_io = smdkv210_map_io,.init_machine = smdkv210_machine_init,.timer = &s5p_systimer,
};
二阶段
修改电源异常
程序在dev_driver_string或max8698_pmic_probe异常
max8698_pmic_probe为电源管理IC驱动安装函数,210未使用电源IC
make menuconfig取消max8698编译进内核
修改网卡异常
修改网卡寄存器配置(移植mach-x210.c)
smdkc110_machine_init==>smdkc110_dm9000_set#ifdef CONFIG_DM9000
static void __init smdkc110_dm9000_set(void)
{unsigned int tmp;s3c_gpio_cfgpin(S5PV210_GPH1(2), S3C_GPIO_INPUT);s3c_gpio_setpull(S5PV210_GPH1(2), S3C_GPIO_PULL_NONE);int ret = gpio_request(S5PV210_GPH1(2), "GPH1");if(ret)printk("mach-x210: request gpio GPH1(2) fail");else{s3c_gpio_cfgpin(S5PV210_GPH1(2), 0xf);s3c_gpio_setpull(S5PV210_GPH1(2), S3C_GPIO_PULL_NONE);}tmp = ((0<<28)|(0<<24)|(5<<16)|(0<<12)|(0<<8)|(0<<4)|(0<<0));__raw_writel(tmp, S5P_SROM_BC1);tmp = __raw_readl(S5P_SROM_BW);tmp &= ~(0xf << 4);tmp |= (1<<7) | (1<<6) | (1<<5) | (1<<4); // dm9000 16bit__raw_writel(tmp, S5P_SROM_BW);tmp = __raw_readl(S5PV210_MP01CON);tmp &= ~(0xf << 4);tmp |= (2 << 4);__raw_writel(tmp, S5PV210_MP01CON);
}
修改网卡地址和中断号(arch/arm/plat-s5p/devs.c)
/* DM9000 registrations */
#ifdef CONFIG_DM9000
static struct resource s5p_dm9000_resources[] = {[0] = {.start = S5P_PA_DM9000,.end = S5P_PA_DM9000,.flags = IORESOURCE_MEM,},[1] = {
#if defined(CONFIG_DM9000_16BIT)//.start = S5P_PA_DM9000 + 2,//.end = S5P_PA_DM9000 + 2,.start = S5P_PA_DM9000 + 4,.end = S5P_PA_DM9000 + 4,.flags = IORESOURCE_MEM,
#else.start = S5P_PA_DM9000 + 1,.end = S5P_PA_DM9000 + 1,.flags = IORESOURCE_MEM,
#endif},[2] = {//.start = IRQ_EINT9,//.end = IRQ_EINT9,.start = IRQ_EINT10,.end = IRQ_EINT10,.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,}
};依据struct platform_device s5p_device_dm9000 = {.name = "dm9000",.id = 0,.num_resources = ARRAY_SIZE(s5p_dm9000_resources),.resource = s5p_dm9000_resources,.dev = {.platform_data = &s5p_dm9000_platdata,}
};
修改bank
(arch/arm/mach-s5pv210/include/mach/map.h)//#define S5PV210_PA_DM9000 (0xA8000000)
#define S5PV210_PA_DM9000 (0x88000000)
#define S5P_PA_DM9000 S5PV210_PA_DM9000
结果显示