u-boot移植与使用

作者

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_BASE0x4000000

//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这个地方。
333
board_f.cinit_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 子网掩码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值