作者
QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118
参考
[U-Boot,v2] Add uboot “fdt_high” enviroment variable
[U-Boot] arm: omap: cm_t35: Remove CONFIG_SYS_BOOTMAPSZ to fix FDT Linux booting
uboot移植,编译及环境变量,启动等方面---from README
[uboot] (番外篇)uboot之fdt介绍
[uboot] (第五章)uboot流程——uboot启动流程
u-boot之环境变量
《Linux Uboot 命令U_BOOT_CMD分析》
uboot移植-内存分布
tools: mkimage: fix build with OpenSSL 1.1.x (FS#182)
U-boot 取消启动延时(bootdelay)
LINUX UBOOT bootdelay设置为0解决办法
代码
ubuntu18.04
在ubuntu18.04上编译错误,应该是GCC版本太新导致,patch一下u-boot,$ patch -p1 < 210-openssl-1.1.x-compat.patch
In file included from tools/lib/rsa/rsa-sign.c:1:0:
./tools/../lib/rsa/rsa-sign.c: In function ‘rsa_remove’:
./tools/../lib/rsa/rsa-sign.c:156:2: warning: ‘ERR_remove_thread_state’ is deprecated [-Wdeprecated-declarations]
ERR_remove_thread_state(NULL);
^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/openssl/evp.h:13:0,
from include/image.h:880,
from ./tools/../lib/rsa/rsa-sign.c:10,
from tools/lib/rsa/rsa-sign.c:1:
/usr/include/openssl/err.h:259:1: note: declared here
DEPRECATEDIN_1_1_0(void ERR_remove_thread_state(void *))
^
In file included from tools/lib/rsa/rsa-sign.c:1:0:
./tools/../lib/rsa/rsa-sign.c: In function ‘rsa_sign_with_key’:
./tools/../lib/rsa/rsa-sign.c:213:2: warning: implicit declaration of function ‘EVP_MD_CTX_cleanup’; did you mean ‘EVP_MD_CTX_create’? [-Wimplicit-function-declaration]
EVP_MD_CTX_cleanup(context);
^~~~~~~~~~~~~~~~~~
EVP_MD_CTX_create
./tools/../lib/rsa/rsa-sign.c: In function ‘rsa_get_exponent’:
./tools/../lib/rsa/rsa-sign.c:279:21: error: dereferencing pointer to incomplete type ‘RSA {aka struct rsa_st}’
if (BN_num_bits(key->e) > 64)
^~
scripts/Makefile.host:108: recipe for target 'tools/lib/rsa/rsa-sign.o' failed
内存分配
以zynq为例,CONFIG_SYS_TEXT_BASE
是0x4000000
//include\configs\zynq-common.h
/* Physical Memory map */
#if defined(CONFIG_CSE_QSPI) || defined(CONFIG_CSE_NOR)
# define CONFIG_SYS_TEXT_BASE 0xFFFC4800
#elif defined(CONFIG_CSE_NAND)
# define CONFIG_SYS_TEXT_BASE 0x00100000
#elif defined(CONFIG_ZYNQ_OCM)
# define CONFIG_SYS_TEXT_BASE 0xFFFC0000
#else
# define CONFIG_SYS_TEXT_BASE 0x4000000
#endif
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_SYS_SDRAM_BASE 0
#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1000)
#define CONFIG_SYS_MALLOC_LEN 0xC00000
#define CONFIG_SYS_INIT_RAM_ADDR 0xFFFF0000
#define CONFIG_SYS_INIT_RAM_SIZE 0x1000
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
CONFIG_SYS_INIT_RAM_SIZE - \
GENERATED_GBL_DATA_SIZE)
分析uboot.lds
和编译生成的uboot.map
,
.bss_start 0x04082cd8 0x0
*(.__bss_start)
.__bss_start 0x04082cd8 0x0 arch/arm/lib/built-in.o
0x04082cd8 __bss_start
0x04082cd8 __bss_base = .
...
...
...
.bss_end 0x040d9094 0x0
*(.__bss_end)
.__bss_end 0x040d9094 0x0 arch/arm/lib/built-in.o
0x040d9094 __bss_end
参考u-boot内存空间分配图,如果spl想给u-boot传参数,可以放在0x4000000 * 2
这个地方。
board_f.c
在init_sequence_f
中的display_text_info
可显示堆栈信息。
从eeprom读取mac地址
u-boot可以从eeprom中获取ip地址,前提是没有定义环境变量ethaddr
,u-boot同样还支持生成随机以太网地址。
//net\eth-uclass.c
static int eth_post_probe(struct udevice *dev)
{
...
/* Check if the device has a MAC address in ROM */
if (eth_get_ops(dev)->read_rom_hwaddr)
eth_get_ops(dev)->read_rom_hwaddr(dev);
...
}
//drivers\net\zynq_gem.c line599
static int zynq_gem_read_rom_mac(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
if (!pdata)
return -ENOSYS;
return zynq_board_read_rom_ethaddr(pdata->enetaddr);
}
//include\configs\xilinx_zynqmp_zcu102.h
#define CONFIG_ZYNQ_GEM_EEPROM_ADDR 0x54
#define CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET 0x20
//board\xilinx\zynqmp\zynqmp.c line333
int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
{
#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
defined(CONFIG_ZYNQ_EEPROM_BUS)
i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
ethaddr, 6))
printf("I2C EEPROM MAC address read failed\n");
#endif
return 0;
}
自动生成MAC地址
通过CPU ID来生成MAC这个比较好,但是查了一下手册Zynq没有,ID应该可在PL里获取,
static void generate_mac_addr(uint8_t *enetaddr)
{
int reg;
reg = DIE_ID_REG_BASE + DIE_ID_REG_OFFSET;
/*
* create a fake MAC address from the processor ID code.
* first byte is 0x02 to signify locally administered.
*/
enetaddr[0] = 0x02;
enetaddr[1] = readl(reg + 0x10) & 0xff;
enetaddr[2] = readl(reg + 0xC) & 0xff;
enetaddr[3] = readl(reg + 0x8) & 0xff;
enetaddr[4] = readl(reg) & 0xff;
enetaddr[5] = (readl(reg) >> 8) & 0xff;
}
console
使Uboot中串口静默,env_common.c
中用到uchar default_environment[]
结构,可以添加CONFIG_EXTRA_ENV_SETTINGS
,
#define CONFIG_EXTRA_ENV_SETTINGS "silent=1\0"
#define CONFIG_SILENT_CONSOLE 1
版本号
版本号version_string
,
//include\version.h
#ifndef __VERSION_H__
#define __VERSION_H__
#include <timestamp.h>
#ifndef DO_DEPS_ONLY
#include "generated/version_autogenerated.h"
#endif
#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""
#endif
#define U_BOOT_VERSION_STRING U_BOOT_VERSION " (" U_BOOT_DATE " - " \
U_BOOT_TIME ")" CONFIG_IDENT_STRING
#ifndef __ASSEMBLY__
extern const char version_string[];
#endif /* __ASSEMBLY__ */
#endif /* __VERSION_H__ */
//include\generated\version_autogenerated.h
#define PLAIN_VERSION "2015.04-fdk-1.0.5-20200723.1722"
#define U_BOOT_VERSION "U-Boot " PLAIN_VERSION
#define CC_VERSION_STRING "arm-xilinx-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.11-30) 4.9.1"
#define LD_VERSION_STRING "GNU ld (Sourcery CodeBench Lite 2014.11-30) 2.24.51.20140217"
u-boot的version
命令,该文件中定义version_string
。
//common\cmd_version.c
const char __weak version_string[] = U_BOOT_VERSION_STRING;
static int do_version(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
printf("\n%s\n", version_string);
#ifdef CC_VERSION_STRING
puts(CC_VERSION_STRING "\n");
#endif
#ifdef LD_VERSION_STRING
puts(LD_VERSION_STRING "\n");
#endif
#ifdef CONFIG_SYS_COREBOOT
printf("coreboot-%s (%s)\n", lib_sysinfo.version, lib_sysinfo.build);
#endif
return 0;
}
把version_string
设置到环境变量。
void main_loop(void)
{
...
#ifdef CONFIG_VERSION_VARIABLE
setenv("ver", version_string); /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */
...
一般u-boot在启动后会把version_string
打印出来,位于,
//common\board_f.c
static init_fnc_t init_sequence_f[] = {
...
display_options, /* say that we are here */
...
}
//lib\display_options.c
int display_options (void)
{
#if defined(BUILD_TAG)
printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
#else
printf ("\n\n%s\n\n", version_string);
#endif
return 0;
}
使用
mmc指令
之前使用gzwrite命令把镜像写入SD卡,之前进Linux系统,/dev目录下很几个mmc相关的文件,现在只有一个mmcblk0,其他的都没有了,网上专门查找了emmc的相关资料,我以为时把emmc的分区表给覆盖了,但其实时SD卡和emmc的芯片架构是不一样的,SD卡就没那些分区。
i2c
用max1668说明,读取通道温度,0x18
为i2c地址,
T2080> i2c
i2c - I2C sub-system
Usage:
i2c bus [muxtype:muxaddr:muxchannel] - show I2C bus info
crc32 chip address[.0, .1, .2] count - compute CRC32 checksum
i2c dev [dev] - show or set current I2C bus
i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device
i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device
i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)
i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)
i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)
i2c probe [address] - test for and show device(s) on the I2C bus
i2c read chip address[.0, .1, .2] length memaddress - read to memory
i2c write memaddress chip address[.0, .1, .2] length [-s] - write memory
to I2C; the -s option selects bulk write in a single transaction
i2c reset - re-init the I2C Controller
i2c speed [speed] - show or set I2C bus speed
T2080> i2c bus
Bus 0: fsl_0
Bus 1: fsl_1
Bus 2: fsl_2
Bus 3: fsl_3
T2080> i2c probe
Valid chip addresses: 18 50 51 7C
T2080> i2c md 0x18 0 1
0000: 1e .
T2080> i2c md 0x18 1 1
0001: 2c ,
T2080> i2c md 0x18 2 1
0002: 22 "
T2080> i2c md 0x18 3 1
0003: 35 5
T2080> i2c md 0x18 4 1
0004: 7f .
命令连接
运算符&&
连接命令,若命令失败则退出不执行下一条命令了,可以换成;
,
setenv lowtempwait 'memloop 0x61000024 0x10 0x10 30; if test $? -ne 0; then gpio clear 51; sleep 1; gpio set 51; fi'
setenv ext4_bootmcmd 'run ext4_fpga_boot && run lowtempwait; run load_ext4_kernel && run load_ext4_dtb && bootm ${kernelnetstart} - ${dtbnetstart}'
环境变量
' '
不会替换变量,不会对$
进行计算," "
会替换变量,常用环境变量,
- bootargs 传给内核的启动参数
- bootcmd 自启动时执行的命令
- bootdelay 执行自动启动的等候秒数,设置为0则不等待,后面无法通过按键进入u-boot升级固件,慎用
- baudrate 串口控制台的波特率
- ipaddr 本机的IP地址
- serverip 服务器端的IP地址
- gatewayip 本机网关
- netmask 子网掩码