kernel(三):kernel移植

        本文主要探讨210官方kernel移植。

配置文件选择

    选择配置文件smdkv210_android_defconfig(arch/arm/configs)

修改主Makefile

    配置cpu架构和交叉编译工具链

    vim Makefile

    ARCH            ?= arm
    CROSS_COMPILE   ?= /root/arm-2009q3/bin/arm-none-linux-gnueabi-

初步编译烧录

ubuntu:

    make smdkv210_android_defconfig
    
    make -j4

    cp -r arch/arm/boot/zImage ~/tftp/



uboot:

    tftp 30008000 zImage

    bootm 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 disabled
        mrc     p15, 0, r9, c0, c0              @ get processor id
        bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
        movs    r10, r5                         @ invalid processor (r5=0)?
        beq     __error_p                       @ yes, error 'p'
        bl      __lookup_machine_type           @ r5=machinfo
        movs    r8, r5                          @ invalid machine (r5=0)?
        beq     __error_a                       @ yes, error 'a'
        bl      __vet_atags
        bl      __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 enabled
        adr     lr, BSYM(__enable_mmu)          @ return (PIC) address
         ARM(   add     pc, r10, #PROCINFO_INITFUNC     )
         THUMB( add     r12, r10, #PROCINFO_INITFUNC    )
         THUMB( mov     pc, r12                         )
ENDPROC(stext)





//led off

led_off:
        ldr r3, =0x11111111
        ldr r4, = 0xE0200240
        str r3, [r4]

        ldr r3, =0xff
        ldr r4, =0xE0200244
        str 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_SMDKC110
    MACHINE_START(SMDKC110, "SMDKC110")
    #elif CONFIG_MACH_SMDKV210
    MACHINE_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

                        结果显示

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值