zoukankan      html  css  js  c++  java
  • 基于tiny4412的Linux内核移植(支持device tree)(一)

    作者信息

    作者: 彭东林

    邮箱:pengdonglin137@163.com

    QQ:405728433

    平台简介

    开发板:tiny4412ADK + S700 + 4GB Flash

    要移植的内核版本:Linux-4.4.0 (支持device tree)

    u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动)

    busybox版本:busybox 1.25

    交叉编译工具链: arm-none-linux-gnueabi-gcc

          (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29))

    概述

        由于目前友善之臂提供的u-boot不支持uImage的引导方式,默认的配置也不支持device tree。同时提供的Linux内核版本是linux-3.0.86,不提供device tree。下面我要做的是修改原生的u-boot,使其支持uImage和device tree,由于Linux-4.4.0已经对tiny4412有很的支持,并且在arch/arm/boot/dts/下已经有了专门针对tiny4412的设备树文件exynos4412-tiny4412.dts,因此需要我们改动的很少。对于最新的Linux-4.4需要使用最新的交叉编译工具链,如果使用友善之臂提供的工具链的话会导致编译错误,工具链的地址可以到下面的地址下载:

        目前首先实现如下功能:用u-boot引导uImage或者zImage,同时将设备信息以设备树的形式传递给Linux内核,而根文件系统以ramdisk的形式传递给内核,因为目前SD卡驱动、eMMC驱动和usb网卡驱动都没有移植。

    步骤

    一、关闭MMU

    友善之臂提供的u-boot默认是把MMU打开的,下面我们先关闭MMU:

    1、修改include/configs/tiny4412.h

    #define CONFIG_ENABLE_MMU

    修改为

    #undef CONFIG_ENABLE_MMU

    2、只关闭MMU还不够,还需要修改u-boot的链接地址

    修改文件board/samsung/tiny4412/config.mk

    CONFIG_SYS_TEXT_BASE = 0xc3e00000

    修改为

    CONFIG_SYS_TEXT_BASE = 0x43e00000

    下面是MMU开启时的地址映射:

    0x0000_0000 -- 0x1FFF_FFFF => A:0x0000_0000 -- 0x1FFF_FFFF
    0x2000_0000 -- 0x3FFF_FFFF => Not Allowed
    0x4000_0000 -- 0x5FFF_FFFF => A:0x4000_0000 -- 0x5FFF_FFFF
    0x6000_0000 -- 0xBFFF_FFFF => Not Allowed
    0xC000_0000 -- 0xDFFF_FFFF => A:0x4000_0000 -- 0X5FFF_FFFF
    0xE000_0000 -- 0xFFFF_FFFF => Not Allowed

    上面的意思是:虽然tiny4412只有1GB的内存,可以访问的物理地址空间是0x4000_0000–0x8000_0000,通过MMU后,可以将地址0xC000_0000 -- 0xDFFF_FFFF 映射到0x4000_0000 -- 0X5FFF_FFFF。

    二、解决u-boot无法引导uImage问题

    友善之臂原生的u-boot使用bootm命令只可以引导zImage类型的kernel,不支持uImage,通过分析bootm命令的实现(common/cmd_bootm.c)发现问题所在。

    做如下修改:

    修改do_bootm函数,

    diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
    index 04622dd..a2cb1ec 100644
    --- a/common/cmd_bootm.c
    +++ b/common/cmd_bootm.c
    @@ -590,6 +590,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
            ulong           load_end = 0;
            int             ret;
            boot_os_fn      *boot_fn;
    +       int             iszImage = 0;
     
     #ifdef CONFIG_SECURE_BOOT
     #ifndef CONFIG_SECURE_BL1_ONLY
    @@ -627,6 +628,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
     
                    images.legacy_hdr_valid = 1;
    
    
    
    +               iszImage = 1;
    +
                    goto after_header_check;
            }
     #endif
    @@ -723,8 +726,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
     
     #if defined(CONFIG_ZIMAGE_BOOT)
     after_header_check:
    -       images.os.os = hdr->;ih_os;
    -       images.ep = image_get_ep (&;images.legacy_hdr_os_copy);
    +       if (iszImage) {
    +               images.os.os = hdr->;ih_os;
    +               images.ep = image_get_ep (&;images.legacy_hdr_os_copy);
    +       }
     #endif
     
     #ifdef CONFIG_SILENT_CONSOLE

    问题是:

    在images.os.os中存放的是加载不同os的函数的索引号,如果是zImage的话,会把hdr->ih_os设置为5,然后在after_header_check处会强制把hdr->ih_os赋值为images.os.os。但是如果要引导的是uImage的话,并不会给hdr->ih_os赋值,即hdr->ih_os的值是随机的,而是直接给images.os.os赋值为5,在after_header_check处会将images.os.os的值覆盖掉,导致下面找到的索引函数错误。

    三、支持设备树

    默认的u-boot配置没有打开设备树。

    1、修改include/configs/tiny4412.h

    增加如下两个宏

    #define CONFIG_OF_LIBFDT
    #define CONFIG_SYS_BOOTMAPSZ (20 << 20)

    第一个宏好理解,那么第二个宏的作用是什么呢?

    do_bootm_linux

        ---> bootm_linux_fdt

                ---> boot_relocate_fdt

    在boot_relocate_fdt中会对设备树镜像重定位:

    of_start = (void *)(unsigned long)lmb_alloc_base(lmb, of_len, 0x1000, 
     
    CONFIG_SYS_BOOTMAPSZ + bootmap_base));

    这个函数的目的是计算将设备树镜像重定位后的目的地址,其中bootmap_base是物理内存的其实地址,即0x4000_0000,如果(CONFIG_SYS_BOOTMAPSZ + bootmap_base)设置的太小的话,相应的of_start也会很小,那么在内核自解压的时候会导致设备树被覆盖,我在调试的时候就是遇到了这个问题,通过将内核自解压前后的设备树的地址(在内核源码的arch/arm/boot/compress/head.S中,设备树的地址保存在寄存器r2或者r8,具体看代码实现)处的物理内存dump出来发现的,具体怎么dump,下面再介绍。

    四、编译u-boot

     make tiny4412_config

     make

    五、烧写u-boot到SD卡

    cd sd_fuse/tiny4412

    ./sd_fusing.sh /dev/sdf

    六、启动信息

    U-Boot 2010.12-00000-gb391276-dirty (Jan 17 2016 - 06:03:22) for TINY4412


    CPU:    S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]
            APLL = 1400MHz, MPLL = 800MHz

    Board:  TINY4412
    DRAM:   1023 MiB

    vdd_arm: 1.2
    vdd_int: 1.0
    vdd_mif: 1.1

    BL1 version:  N/A (TrustZone Enabled BSP)


    Checking Boot Mode ... SDMMC
    REVISION: 1.1
    MMC Device 0: 3803 MB
    MMC Device 1: 3728 MB
    MMC Device 2: N/A
    *** Warning - using default environment

    Net:    No ethernet found.
    Hit any key to stop autoboot:  0
    TINY4412 # dnw 0x40600000     

    // 下载uImage到内存0x40600000,这个版本的u-boot不能把uImage下载到0x40008000,否则会在检查是否覆盖的时候失败
    OTG cable Connected!
    Now, Waiting for DNW to transmit data
    Download Done!! Download Address: 0x40600000, Download Filesize:0x43b798
    Checksum is being calculated.....
    Checksum O.K.
    TINY4412 # dnw 0x41000000      // 下载ramdisk到内存0x41000000
    OTG cable Connected!
    Now, Waiting for DNW to transmit data
    Download Done!! Download Address: 0x41000000, Download Filesize:0x27752e
    Checksum is being calculated...
    Checksum O.K.
    TINY4412 # dnw 0x42000000     // 下载设备树镜像到内存0x42000000
    OTG cable Connected!
    Now, Waiting for DNW to transmit data
    Download Done!! Download Address: 0x42000000, Download Filesize:0xa53a
    Checksum is being calculated.
    Checksum O.K.
    TINY4412 # bootm 0x40600000 0x41000000 0x42000000   

    // 启动命令 bootm + uImage 地址 + ramdisk 地址 + 设备树镜像地址,如果没有的话,用 - 代替
    ## Booting kernel from Legacy Image at 40600000 ...
       Image Name:   Linux-4.4.0-gbd49c0f-dirty
       Image Type:   ARM Linux Kernel Image (uncompressed)
       Data Size:    4437848 Bytes = 4333 KiB
       Load Address: 40008000
       Entry Point:  40008000
       Verifying Checksum ... OK
    ## Loading init Ramdisk from Legacy Image at 41000000 ...
       Image Name:   ramdisk
       Image Type:   ARM Linux RAMDisk Image (gzip compressed)
       Data Size:    2585838 Bytes = 2525 KiB
       Load Address: 00000000
       Entry Point:  00000000
       Verifying Checksum ... OK
    ## Flattened Device Tree blob at 42000000
       Booting using the fdt blob at 0x42000000
       Loading Kernel Image ... OK
    OK
    ## Loading init Ramdisk from Legacy Image at 41000000 ...
       Image Name:   ramdisk
       Image Type:   ARM Linux RAMDisk Image (gzip compressed)
       Data Size:    2585838 Bytes = 2525 KiB
       Load Address: 00000000
       Entry Point:  00000000
       Verifying Checksum ... OK
       Loading Ramdisk to 43a84000, end 43cfb4ee ... OK        // 重定位ramdisk镜像
       Loading Device Tree to 413f2000, end 413ff539 ... OK    // 重定位设备树镜像

    Starting kernel ...

    未完待续。

  • 相关阅读:
    Building a Space Station POJ
    Networking POJ
    POJ 1251 Jungle Roads
    CodeForces
    CodeForces
    kuangbin专题 专题一 简单搜索 POJ 1426 Find The Multiple
    The Preliminary Contest for ICPC Asia Shenyang 2019 F. Honk's pool
    The Preliminary Contest for ICPC Asia Shenyang 2019 H. Texas hold'em Poker
    The Preliminary Contest for ICPC Asia Xuzhou 2019 E. XKC's basketball team
    robotparser (File Formats) – Python 中文开发手册
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/5137941.html
Copyright © 2011-2022 走看看