手上有块以前买的Forlinx OK6410开发板,上面的Nandflash坏块太多也只能使用外部MMC卡来做启动设备,但uboot比较旧,功能支持有限,满足不了我的需求。 故打算移植最近的uboot到上面。
首先,移植第一步:uboot准备
1. 从uboot官网下载源码:http://ftp.denx.de/pub/u-boot/ 。我选了u-boot-2018.09.tar.bz2,作为我的目标
u-boot-2018.09.tar.bz2 | 2018-09-10 23:47 | 12M |
解压源码后,我发现u-boot和以前相比改变有些大,整体目录结构和linux越来越相似了,存在arch/arm , configs/, drivers/等目录,初步看了下顶层Makefile:
342 AS = $(CROSS_COMPILE)as
343 # Always use GNU ld
344 ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)
345 LD = $(CROSS_COMPILE)ld.bfd
346 else
347 LD = $(CROSS_COMPILE)ld
348 endif
349 CC = $(CROSS_COMPILE)gcc
350 CPP = $(CC) -E
351 AR = $(CROSS_COMPILE)ar
352 NM = $(CROSS_COMPILE)nm
353 LDR = $(CROSS_COMPILE)ldr
...
492 config: scripts_basic outputmakefile FORCE
493 $(Q)$(MAKE) $(build)=scripts/kconfig $@
494
495 %config: scripts_basic outputmakefile FORCE
496 $(Q)$(MAKE) $(build)=scripts/kconfig $@
交叉工具链配置宏;%config 目标。行496 ,将config为后缀的目标传入./scripts/kconfig/Makefile中,该Makefile中的行127会将arch/../configs/xxxxx_defconfig ,也就是 configs/的xxxxx_defconfig 作为配置文件。这一点和linux相似。
9 # Added for U-Boot
10 # Linux has defconfig files in arch/$(SRCARCH)/configs/,
11 # on the other hand, U-Boot does in configs/.
12 # Set SRCARCH to .. fake this Makefile.
13 SRCARCH := ..
14
... ...
127 %_defconfig: $(obj)/conf
128 $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
129
130 # Added for U-Boot (backward compatibility)
131 %_config: %_defconfig
132 @:
2. 编译U-boot .
由于我的OK6410开发板是arm1176的内核,所以需要用arm-linux 工具链。不过使用以前的工具链,会提示GCC低的错误
ubuntu@ubuntu:~/workspace/src/uboot-201809$ make O=build
make[1]: Entering directory '/home/ubuntu/workspace/src/uboot-201809/build'
*** Your GCC is older than 6.0 and is not supported
make[1]: *** [../arch/arm/config.mk:66: checkgcc6] Error 1
make[1]: Leaving directory '/home/ubuntu/workspace/src/uboot-201809/build'
make: *** [Makefile:148: sub-make] Error 2
所以,需要找高于6.0的arm-linux-gcc工具链. 到linaro官网查了下:http://releases.linaro.org/components/toolchain/binaries/,选择7.3.1版本的arm-linux-gnueabi作为我的目标
![]() | gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabi.tar.xz | 20-Jun-2018 00:10 | 102.6M | open |
工具链解压到~/Downloads/下,就可以编译了。选择里面同样为samsung平台的smdkc100 作为我的编译目标
export PATH=$HOME/Downloads/7.3.1/bin:$PATH
export CROSS_COMPILE=arm-linux-gnueabi-
make O=build smdkc100_defconfig
make O=build
3. 在uboot上新建smdk6410项目
要使uboot能够编译smdk6410,简单的办法就是参考smdkc100的代码,将项目结构复制一份,并改名成smdk6410。不过在做这些之前,必须厘清,项目代码在uboot中的关联。以下将以smdkc100为例,逐渐分析。
我们先从configs/smdkc100_defconfig 入手,第一行,表示ARM架构的宏。找到CONFIG_ARCH_xxxx和CONFIG_TARGET_xxxx这两个宏, 然后搜索使用的地方
1 CONFIG_ARM=y
2 CONFIG_ARCH_S5PC1XX=y
3 CONFIG_SYS_TEXT_BASE=0x34800000
4 CONFIG_TARGET_SMDKC100=y
搜索结果如下,
ubuntu@ubuntu:~/workspace/src/uboot-201809$ grep -E "CONFIG_ARCH_S5PC1XX|CONFIG_TARGET_SMDK6410" . -r
./arch/arm/Makefile:machine-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx
./configs/smdk6410_defconfig:CONFIG_TARGET_SMDK6410=y
./configs/smdkc100_defconfig:CONFIG_ARCH_S5PC1XX=y
./configs/s5p_goni_defconfig:CONFIG_ARCH_S5PC1XX=y
文件arch/arm/Makefile, 行84,可以看出 CONFIG_ARCH_S5PC1XX 的作用是将arch/arm/mach-s5pc1xx加到编译系统中
71 machine-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx
72 machine-$(CONFIG_ARCH_SUNXI) += sunxi
....
84 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
85
86 PLATFORM_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs))
在查看该宏在arch/arm/Kconfig的定义,select语句表示这些将随该宏一起打开,需要根据实际情况配置这些宏,S5PC1XX处理器是ARMv7, 若是其他core则需修改。
617 config ARCH_S5PC1XX
618 bool "Samsung S5PC1XX"
619 select CPU_V7A
620 select DM
621 select DM_GPIO
622 select DM_I2C
623 select DM_SERIAL
624 imply CMD_DM
252 config SYS_CPU
253 default "arm720t" if CPU_ARM720T
254 default "arm920t" if CPU_ARM920T
255 default "arm926ejs" if CPU_ARM926EJS
256 default "arm946es" if CPU_ARM946ES
257 default "arm1136" if CPU_ARM1136
258 default "arm1176" if CPU_ARM1176
259 default "armv7" if CPU_V7A
260 default "armv7" if CPU_V7R
261 default "armv7m" if CPU_V7M
262 default "pxa" if CPU_PXA
263 default "sa1100" if CPU_SA1100
264 default "armv8" if ARM64
265
之后,进入arch/arm/mach-s5pc1xx/下,进一步查看依赖关系,分别查看Makefile和Kconfig
arch/arm/mach-s5pc1xx/Makefile
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2008
# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
obj-y = cache.o
obj-y += reset.o
obj-y += clock.o
arch/arm/mach-s5pc1xx/Kconfig
if ARCH_S5PC1XX
choice
prompt "S5PC1XX board select"
optional
config TARGET_S5P_GONI
bool "S5P Goni board"
select OF_CONTROL
config TARGET_SMDKC100
bool "Support smdkc100 board"
select OF_CONTROL
endchoice
config SYS_SOC
default "s5pc1xx"
source "board/samsung/goni/Kconfig"
source "board/samsung/smdkc100/Kconfig"
endif
Kconfig中的行21, 表示将包含board/samsung/smdkc100/Kconfig 文件内容如下
if TARGET_SMDKC100
config SYS_BOARD
default "smdkc100"
config SYS_VENDOR
default "samsung"
config SYS_SOC
default "s5pc1xx"
config SYS_CONFIG_NAME
default "smdkc100"
endif
这两个Kconfig分别定义了宏:
CONFIG_SYS_SOC
CONFIG_SYS_BOARD
CONFIG_SYS_VENDOR
CONFIG_SYS_SOC
CONFIG_SYS_CONFIG_NAME
在顶层config.mk中, 这些宏将会被作为目标路径的一部分,并定义了CPUDIR BOARDDIR SOC VENDOR
23 ARCH := $(CONFIG_SYS_ARCH:"%"=%)
24 CPU := $(CONFIG_SYS_CPU:"%"=%)
...
30 BOARD := $(CONFIG_SYS_BOARD:"%"=%)
31 ifneq ($(CONFIG_SYS_VENDOR),)
32 VENDOR := $(CONFIG_SYS_VENDOR:"%"=%)
33 endif
34 ifneq ($(CONFIG_SYS_SOC),)
35 SOC := $(CONFIG_SYS_SOC:"%"=%)
36 endif
...
41 # CPU-specific code.
42 CPUDIR=arch/$(ARCH)/cpu$(if $(CPU),/$(CPU),)
...
50 ifneq ($(BOARD),)
51 ifdef VENDOR
52 BOARDDIR = $(VENDOR)/$(BOARD)
53 else
54 BOARDDIR = $(BOARD)
55 endif
几个关键配置路径,与配置宏的关系
- board/samsung/smdkc100/Makefile
宏表示路径:$(srctree)/board/$(BOARDDIR)/Makefile - arch/arm/cpu/armv7/Makefile
宏表示路径:$(srctree)/$(CPUDIR)/Makefile - arch/arm/mach-s5pc1xx/include/mach/
宏表示路径:$(srctree)/arch/$(ARCH)/mach-$(SOC)/include/mach - include/configs/smdkc100.h
宏表示路径:$(srctree)/include/configs/$(CONFIG_SYS_CONFIG_NAME).h
到这里, 我们已经知道了,在uboot新建一个需要涉及到的文件路径,以smdkc100为例,列出:
configs/smdkc100_defconfig
arch/arm/mach-s5pc1xx/
board/samsung/smdkc100/
include/configs/smdkc100.h
以同样的结构,建立smdk6410新项目
下一节,将讲述porting过程。
(待续... ...)