您的位置:首页 > 运维架构 > Linux

基于tiny4412的Linux内核移植(支持device tree)(一)

2016-01-17 22:12 531 查看

作者信息

作者:彭东林

邮箱:pengdonglin137@163.com

QQ:405728433

平台简介

开发板:tiny4412ADK+S700+4GBFlash

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

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

busybox版本:busybox1.25

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

(gccversion4.8.320140320(prerelease)(SourceryCodeBenchLite2014.05-29))

概述

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

GCCARMEmbedded

ARM交叉编译工具链

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

步骤

一、关闭MMU

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

1、修改include/configs/tiny4412.h



#defineCONFIG_ENABLE_MMU

修改为

#undefCONFIG_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=>NotAllowed
0x4000_0000--0x5FFF_FFFF=>A:0x4000_0000--0x5FFF_FFFF
0x6000_0000--0xBFFF_FFFF=>NotAllowed
0xC000_0000--0xDFFF_FFFF=>A:0x4000_0000--0X5FFF_FFFF
0xE000_0000--0xFFFF_FFFF=>NotAllowed

上面的意思是:虽然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函数,

[code]diff--gita/common/cmd_bootm.cb/common/cmd_bootm.c


index04622dd..a2cb1ec100644


---a/common/cmd_bootm.c


+++b/common/cmd_bootm.c


@@-590,6+590,7@@intdo_bootm(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[])


ulongload_end=0;


intret;


boot_os_fn*boot_fn;


+intiszImage=0;




#ifdefCONFIG_SECURE_BOOT


#ifndefCONFIG_SECURE_BL1_ONLY


@@-627,6+628,8@@intdo_bootm(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[])




images.legacy_hdr_valid=1;




+iszImage=1;


+


gotoafter_header_check;


}


#endif


@@-723,8+726,10@@intdo_bootm(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[])




#ifdefined(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




#ifdefCONFIG_SILENT_CONSOLE

[/code]

问题是:

在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

增加如下两个宏

#defineCONFIG_OF_LIBFDT
#defineCONFIG_SYS_BOOTMAPSZ(20<<20)

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

do_bootm_linux

--->bootm_linux_fdt

--->boot_relocate_fdt

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

of_start=(void*)(unsignedlong)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

maketiny4412_config

make

五、烧写u-boot到SD卡

cdsd_fuse/tiny4412

./sd_fusing.sh/dev/sdf

六、启动信息

U-Boot2010.12-00000-gb391276-dirty(Jan172016-06:03:22)forTINY4412

CPU:S5PC220[SamsungSOConSMPPlatformBaseonARMCortexA9]
APLL=1400MHz,MPLL=800MHz

Board:TINY4412
DRAM:1023MiB

vdd_arm:1.2
vdd_int:1.0
vdd_mif:1.1

BL1version:N/A(TrustZoneEnabledBSP)

CheckingBootMode...SDMMC
REVISION:1.1
MMCDevice0:3803MB
MMCDevice1:3728MB
MMCDevice2:N/A
***Warning-usingdefaultenvironment

Net:Noethernetfound.
Hitanykeytostopautoboot:0
TINY4412#dnw0x40600000

//下载uImage到内存0x40600000,这个版本的u-boot不能把uImage下载到0x40008000,否则会在检查是否覆盖的时候失败
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x40600000,DownloadFilesize:0x43b798
Checksumisbeingcalculated.....
ChecksumO.K.
TINY4412#dnw0x41000000//下载ramdisk到内存0x41000000
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x41000000,DownloadFilesize:0x27752e
Checksumisbeingcalculated...
ChecksumO.K.
TINY4412#dnw0x42000000//下载设备树镜像到内存0x42000000
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x42000000,DownloadFilesize:0xa53a
Checksumisbeingcalculated.
ChecksumO.K.
TINY4412#bootm0x406000000x410000000x42000000

//启动命令bootm+uImage地址+ramdisk地址+设备树镜像地址,如果没有的话,用-代替
##BootingkernelfromLegacyImageat40600000...
ImageName:Linux-4.4.0-gbd49c0f-dirty
ImageType:ARMLinuxKernelImage(uncompressed)
DataSize:4437848Bytes=4333KiB
LoadAddress:40008000
EntryPoint:40008000
VerifyingChecksum...OK
##LoadinginitRamdiskfromLegacyImageat41000000...
ImageName:ramdisk
ImageType:ARMLinuxRAMDiskImage(gzipcompressed)
DataSize:2585838Bytes=2525KiB
LoadAddress:00000000
EntryPoint:00000000
VerifyingChecksum...OK
##FlattenedDeviceTreeblobat42000000
Bootingusingthefdtblobat0x42000000
LoadingKernelImage...OK
OK
##LoadinginitRamdiskfromLegacyImageat41000000...
ImageName:ramdisk
ImageType:ARMLinuxRAMDiskImage(gzipcompressed)
DataSize:2585838Bytes=2525KiB
LoadAddress:00000000
EntryPoint:00000000
VerifyingChecksum...OK
LoadingRamdiskto43a84000,end43cfb4ee...OK//重定位ramdisk镜像
LoadingDeviceTreeto413f2000,end413ff539...OK//重定位设备树镜像

Startingkernel...

未完待续。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: