文章目录
1 UBOOT
1.添加开发板(芯片)配置文件
即 config 目录中,创建一个 deconfig 文件
2.添加开发板(芯片)头文件
在 include/configs/ ----> mx6ullevk.h mx6ull_alientek_emmc.h
3.添加开发板对应的板级文件夹
uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上 <外设驱动文件> 等等
在 board/freescale/
要修改的有:
1.Make file
2.xxx.cfg文件
3. Kconfig
4. MAINTAINERS
4.(也可以)修改 U-Boot 图形界面配置文件
2.kernal
1.添加开发板默认配置文件 arch/arm/configs
cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig
后 输入
make imx_alientek_emmc_defconfig
进行配置
——————————————————————————————————————————————————————————————————————————————————————————————————————
2 添加开发板对应的设备树文件 arch/arm/boot/dts
cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts
——————————————————————————————————————————————————————————————————————————————————————————————————————
3.运行build.sh
4.
arch/arm/boot ------->zImage 镜像文件
arch/arm/boot/dts------>imx6ull-alientek-emmc.dtb
一.U-boot
1.Uboot初次编译
1.首先在 Ubuntu 中安装 ncurses 库, 否则编译会报错,安装命令如下:
sudo apt-get install libncurses5-dev
2.在把u-boot拷贝到一个文件件,执行
tar -vxjf 《压缩包名字》
3.执行里面带有.sh的文件
./build.sh
4.这个.bin文件就可以烧写了
2. 编译烧录
创建完Makefile后
输入 make
1.将 imxdownload 复制到工作目录中
2.给予 imxdownload 可执行权限
执行 chmod 777 imxdownload
(这时候 如果 ls 下 会看到imxdownload 变绿了 表示是可以执行)
3.插入读卡器 执行 ls /dev/sd* 可以看到设备名称
(可以在插入读卡器前、后分别执行下,看看是哪个设备)
4.最后执行
./imxdownload led.bin /dev/sdb
(我的设备是 /dev/sdb,)
注意:如果这个烧写速度大于几十 MB/s、甚至几百 MB/s 那么肯定是烧写失败了!
插入SD卡 拨码开关如图
3.u-boot 启动
1.插上内存卡,把数据线插上开发板,后找到串口;
2.打开MobaXterm ,右上角Session—>串口
3.进行如下设置
4.按下开发板上的 RESET
弹出如下信息:
4.U-Boot 命令使用
1–.help
2–.bdinfo此命令用于查看板子信息
上面包含了:
DRAM 的起始地址和大小、
启动参数保存起始地址、
波特率、
sp(堆栈指针)起始地址等信息
3–.printenv 用于输出环境变量信息
1.有 baudrate、 board_name、 board_rec、 boot_fdt、 bootcmd等等。
2.uboot 中的环境变量都是字符串,既然叫做环境变量,那么它的作用就和“变量”一样。
3.比如 bootdelay 这个环境变量就表示 uboot 启动延时时间,默认 bootdelay=3,也就默认延时 3秒。前面说的 3 秒倒计时就是由 bootdelay 定义的,如果将 bootdelay 改为 5 的话就会倒计时 5s了
4–.环境变量操作命令
1>.setenv 用于设置或者修改环境变量的值
2>.saveenv 用于保存修改后的环境变量
一般环境变量是存放在外部 flash 中的,uboot 启动的时候会将环境变量从 flash 读取到 DRAM 中。
所以使用命令 setenv 修改的是 DRAM中的环境变量值,修改以后要使用 saveenv 命令将修改后的环境变
量保存到 flash 中,否则的话uboot 下一次重启会继续使用以前的环境变量值。
1----.修改环境变量
比如我们要将环境变量 bootdelay 改为 5,就可以使用如下所示命令:
setenv bootdelay 5
saveenv
有时候我们修改的环境变量值可能会有空格, 比如 bootcmd、 bootargs 等, 这个时候环境变量值就得用单引号括起来,比如下面修改环境变量 bootargs 的值:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
2----.新建环境变量
setenv author zuozhongkai
saveenv
3----.删除环境变量(即是:赋空)
setenv author
saveenv
5.内存操作命令
1> md 显示内存值
md[.b, .w, .l] address [# of objects]
命令中的[.b .w .l]对应 byte、 word 和 long,也就是分别以 1 个字节、 2 个字节、 4 个字节
来显示内存值。 address 就是要查看的内存起始地址, [# of objects]表示要查看的数据长度,
这个数据长度单位不是字节,而是跟你所选择的显示格式有关。比如你设置要查看的
内存长度为20(十六进制为 0x14),如果显示格式为.b 的话那就表示 20 个字节;如果
显示格式为.w 的话就表示 20 个 word,也就是 20*2=40 个字节;如果显示格式为.l 的
话就表示 20 个 long,也就是20*4=80 个字节。
uboot 命令中的数字都是十六进制的!不是十进制的!
比如你想查看以 0X80000000 开始的 20 个字节的内存值,显示格式为.b 的话,应该使用
如下所示命令:
md.b 80000000 14
执行结果 显示的是每个储存单元寸的值是多少;
2> nm 修改指定地址的内存值
nm [.b, .w, .l] address
nm 命令同样可以以.b、 .w 和.l 来指定操作格式,比如现在以.l 格式修改 0x80000000 地址
的数据为 0x12345678。输入命令:
nm.l 80000000
在图 30.4.3.2 中, 80000000 表示现在要修改的内存地址, 0500e031 表示地址 0x80000000 现在的数据,?后面就可以输入要修改后的数据 0x12345678,enter 一下后再输入q就行了
3> mm 修改指定 连续 地址内存值的
修改 连续地址
4> mv/cp/cmp命令…
6 网络操作命令
setenv ipaddr 192.168.1.50
setenv ethaddr b8:ae:1d:01:00:00
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.253
saveenv
1> ping 命令
开发板的网络能否使用?
是否可以和服务器(Ubuntu 主机)进行通信?
通过 ping 命令就可以验证
比如 ping 192.168.1.253
注意:只能uboot 中 ping 其他的机器,其他机器不能 ping uboot,因为 uboot 没有对 ping
命令做处理,如果用其他的机器 ping uboot 的话会失败!
2>dhcp 用于从路由器获取 IP 地址
开发板通过 dhcp 获取到的 IP 地址为 192.168.1.137
在图 中可以看到“warning: no boot file name;”、“TFTP from server 192.168.1.1”
这是因为 DHCP 不单单是获取 IP 地址,其还会通过 TFTP 来启动 linux 内核
输入“? dhcp”即可查看 dhcp 命令详细的信息
后续整理中…
二.U-Boot 顶层 Makefile 详解
1.arch
2.board
3.configs
uboot 是可配置的,configs中的文件是配置uboot的,
使用“make xxx_defconfig”命令即可配置 uboot,
比如:
make mx6ull_14x14_ddr512_emmc_defconfig
4. Makefile 文件
整理太麻烦了 直接去 正点原子linux驱动开发指南735页 吧😂
Makefile
命令输出
uboot 默认编译是不会在终端中显示完整的命令,都是短命令,不利于分析 uboot 的编译过程
//Makefile中 70行左右
ifeq ("$(origin V)", "command line")//表示V的来源,
如果变量 V 是在命令行定义的那么它的来源就
是"command line",这 样"$(origin V)"和
"commandline"就 相等了
KBUILD_VERBOSE = $(V) // KBUILD_VERBOSE 等于V
比如在命令行中输 入 “ V=1 “
的话那么KBUILD_VERBOSE=1
endif
ifndef KBUILD_VERBOSE //如 果 没 有 在 命 令 行 输 入 V 的 话KBUILD_VERBOSE=0
KBUILD_VERBOSE = 0
endif
ifeq ($(KBUILD_VERBOSE),1) //判断 KBUILD_VERBOSE 是否为 1
quiet = //为1的话,则....
Q =
else //不为1的话,则...
quiet=quiet_
Q = @
endif
Makefile 中会用到变量 quiet 和 Q 来控制编译的时候是否在终端输出完整的命令,在顶层
Makefile 中有很多如下所示的命令:
$(Q)$(MAKE) $(build)=tools
V=0
上述命令展开就是“@ make $(build)=tools”, make 在执行的时候默认会在终
端输出命令,但是在命令前面加上“@”就不会在终端输出命令了。
当 V=1
Q 就为空,上述命令就是“make $(build)=tools”,因此在 make 执行的过程,命令会被完整的输出在终端上。
有些命令会有两个版本,比如:
quiet_cmd_sym ?= SYM $@
cmd_sym ?= $(OBJDUMP) -t $< > $@
sym 命令分为“quiet_cmd_sym”和“cmd_sym”两个版本,这两个命令的功能都是一样的,
区别在于 make 执行的时候输出的命令不同。
quiet_cmd_xxx 命令输出信息少,也就是短命令,
而 cmd_xxx 命令输出信息多,也就是完整的命令。
如果变量 quiet 为空的话,整个命令都会输出。
如果变量 quiet 为“quiet_”的话,仅输出短版本。
如果变量 quiet 为“silent_”的话,整个命令都不会输出。
静默输出
# If the user is running make -s (silent mode), suppress echoing of
# commands
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4 //$(filter4.%,$(MAKE_VERSION))不为空的话条件就成立
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
quiet=silent_
endif
else # make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
quiet=silent_
endif
endif
export quiet Q KBUILD_VERBOSE
filter 函数表示以 pattern 模式过滤 text 字符串中的单词,仅保留符合模式 pattern 的单词,可以有多个模式。
函数返回值就是符合 pattern 的字符串。
因此
$(filter 4.%,$(MAKE_VERSION))
的含义就是在字符串“ MAKE_VERSION”中找出符合“ 4.%”的字符(%为通配符),
MAKE_VERSION 是make工具的版本号, ubuntu16.04里面默认自带的make工具版本号为4.1,
大家可以输入“make -v”查看。
。。。。。。。。。。。。。。。。。。。。。。
编译输出目录设置 O
“make O=out”就是设置目标文件输出到 out 目录
ifeq ("$(origin O)", "command line") #如果O来自命令行
KBUILD_OUTPUT := $(O) #比如:make O=outfile ,KBUILD_OUTPUT=输出目录
endif
第 135 行判断 KBUILD_OUTPUT 是否为空。
第 139 行调用 mkdir 命令,创建 KBUILD_OUTPUT 目录,并且将创建成功以后的绝对路径赋值给 KBUILD_OUTPUT。至此,通过 O 指定的输出目录就存在了
代码检查 C
命令“make C=1”使能代码检查,检查那些需要重新编译的文件。
“make C=2”用于检查所有的源码文件
#KBUILD_CHECKSRC代码检查
#KBUILD_CHECKSRC=1检查需要重新编译的文件
#KBUILD_CHECKSRC=2检查所有源码文件
ifdef SUBDIRS #兼容老语法make SUBIDRS=dir
KBUILD_EXTMOD ?= $(SUBDIRS)
ifeq ("$(origin C)", "command line")
KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRC
KBUILD_CHECKSRC = 0
endif
指定模块编译 M
第 197 行
如果 KBUILD_EXTMOD 为空------>目标_all 依赖 all,
因此要先编译出 all。否则的话默认目标_all 依赖 modules,要先编译出 modules,也就是编译模块。一般情况
下我们不会在 uboot 中编译模块,所以此处会编译 all 这个目标。
第 203 行判断 KBUILD_SRC 是否为空,如果为空的话就设置变量 srctree 为当前目录,即
srctree 为“.”,一般不设置 KBUILD_SRC。
第 214 行设置变量 objtree 为当前目录。
第 215 和 216 行分别设置变量 src 和 obj,都为当前目录。
第 218 行设置 VPATH。
第 220 行导出变量 scrtree、 objtree 和 VPATH。
获取主机架构和系统
1. shell 中的“|”表示管道,意思是将左边的输出作为右边的输入
2. sed -e 是替换命令,“sed -e s/i.86/x86/”表示将管道输入的字符串中的“i.86”替换为“x86”
设 置 目 标 板 架 构 // 交 叉 编 译 器
第 245 行判断 HOSTARCH 和 ARCH 这两个变量是否相等,
主机架构(变量 HOSTARCH)是x86_64,而我们编译的是 ARM 版本 uboot,肯定不相等
所以 CROSS_COMPILE= arm-linuxgnueabihf-。
从示例代码 31.3.9.1 可以看出,每次编译 uboot 的时候都要在 make 命令后面设置
ARCH 和 CROSS_COMPILE,使用起来很麻烦,
可以直接修改顶层 Makefile,在里面加入 ARCH和 CROSS_COMPILE 的定义,如图 31.3.9.1 所示:
第 249 行定义变量 KCONFIG_CONFIG, uboot 是可以配置的,这里设置配置文件为.config, .config 默认是没有的,需要使用命令
make xxx_defconfig”对 uboot 进行配置,配置完成以后就会在 uboot 根目录下生成.config。默认情况下.config 和xxx_defconfig 内
容是一样的,因为.config 就是从 xxx_defconfig 复制过来的。如果后续自行调整了 uboot 的一些配置参数,那么这些新的配置参数
就添加到了.config 中,而不是 xxx_defconfig。相当于 xxx_defconfig 只是一些初始配置,而.config 里面的才是实时有效的配置。
调用 scripts/Kbuild.include
主 Makefile 会调用文件 scripts/Kbuild.include 这个文件,顶层 Makefile 中代码如下:
示例代码 31.3.10.1 顶层 Makefile 代码
327 # We need some generic definitions (do not try to remake the file).
328 scripts/Kbuild.include: ;
329 include scripts/Kbuild.include
交叉编译工具变量设置
导出其他变量
三.u-boot 启动流程
…其他
U-boot移植
编译
有3中方法
1.直接在命令行输入:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
2.也可以创建一个sh脚本
#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihfmx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
然后授权 在执行
./mx6ull_14x14_evk_emmc.sh
就行了
3.也可以修改Makefile