基于tiny4412的Linux内核移植(支持device tree)(一)
2016-01-17 22:12
531 查看
作者信息
作者:彭东林邮箱:
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需要使用最新的交叉编译工具链,如果使用友善之臂提供的工具链的话会导致编译错误,工具链的地址可以到下面的地址下载:目前首先实现如下功能:用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...
未完待续。
相关文章推荐
- Linux学习笔记:MySQL的授权
- 【Linux】和【Mac】下修改终端提示文字和主机名的方法
- linux编程之内存映射
- Linux内核同步机制之completion
- linux中关于DNS的配置
- linux 常用命令
- linux vi编辑器
- linux trap命令举例
- 【转】centos7安装
- linux搭建ntp服务
- 嵌入式Linux研发,非常值得研究的几个开源项目
- Linux(Ubuntu)环境下使用Fiddler
- 【Linux】新建用户、用户组以及为新用户分配权限
- Linux学习笔记:MySQL字符集
- Linux学习笔记:创建用户与授权
- Linux学习笔记:挂载点的选项noexec
- 【linux】500 OOPS:cannot change directory:/root
- Linux内核构建系统之十
- Linux内核构建系统之九
- Linux内核构建系统之七