当前位置:网站首页>Talk about SOC startup (IX) adding a new board to uboot
Talk about SOC startup (IX) adding a new board to uboot
2022-07-07 11:26:00 【lgjjeff】
This paper is based on the following software and hardware assumptions :
framework :AARCH64
Software :Uboot 2021.10-rc1
1 Uboot Code level
uboot Need to support a large number of hardware , And it has good scalability 、 Portability and maintainability , Therefore, there must be a well-designed code architecture . The design of code architecture is always inseparable from the software and hardware architecture , At the hardware level, the core of embedded system generally includes the following levels :
(1) Target board : It contains all the components required for the operation of the system , Such as SOC chip 、DDR、flash/emmc Memory 、 Various peripherals and clock sources 、 Power management chip, etc
(2)SOC: It contains cpu、 Bus controller 、 Integrated on chip rom、sram、dma controller 、 Hardware accelerator 、 Isomeric nucleus , And the on-chip clock 、 Power control module
(3) Processor architecture : It generally refers to the large version of processor architecture , There may be different instruction sets between different architectures 、 Exception model and memory model . For example, for arm Series architecture ,armv8 and armv7 It belongs to different processor architectures
(4)cpu model : It refers to the specific model of the processor , Such as cortex-a53 or cortex-a72 etc.
commonly cpu The number of models and processor architectures is relatively small , As for the arm Generally speaking, architecture is arm These models are officially released . and soc More models , It is mainly based on specific cpu Architecture and others ip modular , Designed special or general purpose chip , Such as mobile phone chips designed by Qualcomm or Hisilicon . The last is to soc Chip as the core design of the target board , Basically, all components required for a product are integrated on the target board , Such as the circuit board of a mobile phone . The simple relationship between them is shown in the figure below :
Uboot The code design of also follows the above levels ,arch The directory contains the code related to the processor architecture ,arch/cpu The directory contains specific cpu Code , and board The directory contains the code of a specific target board . So when we add a new target board , The main work can be concentrated on board Related code , As long as it's not too new cpu model ,arch and cpu Relevant code in uboot It has been supported in the official version . Therefore, this part of the implementation can be reused directly , The only thing we have to do is choose the right configuration options
2 How to add board
2.1 add to board Basic steps
When we start a new project , Always hope to make the system work first , Then add more feature, This system contains only the modules needed to make the system run , It is called the minimum system .cpu Normal operation includes the following conditions :
(1) Have proper power supply and clock
(2) The program code is loaded into the appropriate location ,cpu Can get instructions normally
(3) have cpu Read / write memory for data operations
(4)cpu By release reset
Of course, for systems that need to support interrupts , You also need to include an interrupt controller , For systems such as operating systems that require timer driven process switching , Obviously, it still needs timer Timer . In order to achieve the above , We add board The basic steps are as follows :
(1) stay board New under directory board Add a directory , To hold board Specific code
(2) Add Kconfig Configuration options and Makefile Compilation options , Add it to the compilation system
(3) stay Kconfig In order to board Define a configuration item , And add the supported features for the configuration item , Such as cpu framework 、cpu Model, etc
(4) As new board Add a header file related to configuration and required for compilation defconfig file , Used for board Related options configuration
(5) stay board Add appropriate files to the directory , And implement the necessary interfaces
2.2 test board Add examples
Next, we will customize a target board test, The board With armv8 Architecturally qemu virtual machine virt machine As hardware , And in board After the addition is completed, it can be added through qemu Perform relevant functional tests . The name of the target board is as follows :
vendor:mars
board:test
2.2.1 add to target configuration option
(1) stay arch/arm/Kconfig Of board select Add the following... Under the menu TARGET_TESTBOARD configuration option :
config TARGET_TESTBOARD
bool "Qemu test board"
select ARM64
select DM
select DM_SERIAL
select PL01X_SERIAL
select SUPPORT_SPL
select SPL if SUPPORT_SPL
select SPL_FRAMEWORK_BOARD_INIT_F if SPL
select SPL_SERIAL_SUPPORT
select PL011_SERIAL if SPL
select SPL_LIBGENERIC_SUPPORT if SPL
select SPL_LIBCOMMON_SUPPORT if SPL
This option will be shown later configs/testboard_defconfig Pass through CONFIG_ TARGET_TESTBOARD =y choice
(2) stay arch/arm/Kconfig Add the following to the file , To include board Of Kconfig file
source "board/mars/test/Kconfig"
2.2.2 add to config The header file
stay include/configs Add under directory config The header file testboard.h, And add the following :
#ifndef __CONFIG_H
#define __CONFIG_H
#include <linux/sizes.h>
#define CONFIG_SYS_SDRAM_BASE 0x40000000
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M)
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M)
#define CONFIG_SYS_MALLOC_LEN SZ_16M
#define CONFIG_SYS_BOOTM_LEN SZ_64M
#define CONFIG_SYS_HZ 1000
#define CONFIG_PL01x_PORTS {
(void *)(0x9000000)}
#define CONFIG_PL011_CLOCK 1
#define CONFIG_SYS_UBOOT_START 0x40300000
#define BOOT_TARGET_DEVICES(func) \ func(VIRTIO, virtio, 0)
#define CONFIG_EXTRA_ENV_SETTINGS \ "fdt_addr=0x43000000\0" \ "kernel_addr_r=0x40000000\0" \ "bootargs=earlycon root=/dev/vda\0" \ "bootcmd=smhload /home/lgj/work/linux/arch/arm64/boot/Image ${kernel_addr_r};" \ "smhload /home/lgj/work/linux/arch/arm64/boot/dts/qemu/test-board-smc.dtb ${fdt_addr};" \ "booti ${kernel_addr_r} - ${fdt_addr}\0"
#define CONFIG_SYS_CBSIZE 512
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 2
#define CONFIG_SYS_MAX_FLASH_SECT 256 /* Sector: 256K, Bank: 64M */
#define CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
#define CONFIG_SPL_MAX_SIZE 0x25000
#define CONFIG_SPL_STACK (CONFIG_SYS_SDRAM_BASE + SZ_1M)
#define CONFIG_SPL_BSS_START_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_1M)
#define CONFIG_SPL_BSS_MAX_SIZE 0x1000
#endif
2.2.3 add to dtb file
Use qemu The simulator starts uboot when , The simulator will provide a default dtb file , But we can also use our own customized dtb file , Here's the custom dtb Method of file :
(1) stay arch/arm/dts/ Add under directory dts file test-board-minimal.dts, And in the Makefile Add the following compilation options
dtb-$(CONFIG_TARGET_TESTBOARD) += test-board-minimal.dtb
(2) In compiling the configuration file configs/testboard_defconfig Specified in the dtb As the default dtb file , And enable uboot Device tree support
CONFIG_DEFAULT_DEVICE_TREE="test-board-minimal"
CONFIG_OF_CONTROL=y
CONFIG_OF_SEPARATE=y
2.2.4 add to board file
(1) stay board Create under directory mars/test Catalog
(2) stay board/mars/test Create under directory Kconfig file , And add the following
if TARGET_TESTBOARD
config SYS_VENDOR
default "mars"
config SYS_BOARD
default "test"
config SYS_CONFIG_NAME
default "testboard"
endif
among :
SYS_VENDOR: Used to specify the board Of vendor name , It is associated with SYS_BOARD Make sure it will be compiled board Code path .
namely board/< SYS_VENDOR >/common and board/< SYS_VENDOR >/< SYS_BOARD > Under the path of Makefile Will be performed , In our example, the directory is board/mars/common/ and board/mars/test/
SYS_BOARD: Used to specify the board/< SYS_VENDOR > Next, you need to compile board route , If the directory under the current configuration is board/mars/test/
SYS_CONFIG_NAME Is used to specify the include/configs Header file name under directory , If this file is currently configured, it will be include/configs/testboard.h
(3) stay board/mars/test Create under directory MAINTAINERS file , And add the following
QEMU QEMU TEST BOARD
M: [email protected].com
S: Maintained
F: board/mars/test
F: include/configs/testboard.h
F: configs/testboard.h
(4) stay board/mars/test Create under directory Makefile file , And add the following
obj-y += testboard.o
(5) establish board/mars/test Create under directory testboard.c file , And add the following
#include <common’s>
#include <cpu_func.h>
#include <fdtdec.h>
#include <init.h>
#include <spl.h>
#ifdef CONFIG_ARM64
#include <asm/armv8/mmu.h>
static struct mm_region testboard_mem_map[] = {
{
/* Flash */
.virt = 0x00000000UL,
.phys = 0x00000000UL,
.size = 0x08000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
/* Lowmem peripherals */
.virt = 0x08000000UL,
.phys = 0x08000000UL,
.size = 0x38000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* RAM */
.virt = 0x40000000UL,
.phys = 0x40000000UL,
.size = 255UL * SZ_1G,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
/* Highmem PCI-E ECAM memory area */
.virt = 0x4010000000ULL,
.phys = 0x4010000000ULL,
.size = 0x10000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* Highmem PCI-E MMIO memory area */
.virt = 0x8000000000ULL,
.phys = 0x8000000000ULL,
.size = 0x8000000000ULL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* List terminator */
0,
}
};
struct mm_region *mem_map = testboard_mem_map;
#endif
int board_init(void)
{
return 0;
}
int dram_init(void)
{
if (fdtdec_setup_mem_size_base() != 0)
return -EINVAL;
return 0;
}
int dram_init_banksize(void)
{
fdtdec_setup_memory_banksize();
return 0;
}
void *board_fdt_blob_setup(void)
{
/* QEMU loads a generated DTB for us at the start of RAM. */
return (void *)CONFIG_SYS_SDRAM_BASE;
}
void enable_caches(void)
{
icache_enable();
dcache_enable();
}
#ifdef CONFIG_SPL
u32 spl_boot_device(void)
{
return BOOT_DEVICE_SEMIHOSTING;
}
#endif
2.2.5 establish defconfig The configuration file
stay configs Directory for testboard create profile testboard_defconfig, And add the following
CONFIG_ARM=y
CONFIG_TARGET_TESTBOARD=y
CONFIG_POSITION_INDEPENDENT=y
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x40000
CONFIG_ENV_SECT_SIZE=0x40000
CONFIG_DEFAULT_DEVICE_TREE="test-board-minimal"
CONFIG_ENV_ADDR=0x4000000
CONFIG_OF_CONTROL=y
CONFIG_OF_SEPARATE=y
CONFIG_DM_SERIAL=y
CONFIG_DM_ETH=y
CONFIG_SYSRESET=y
CONFIG_SEMIHOSTING=y
# add boot stage info to fdt
CONFIG_OF_FDT=y
CONFIG_SPL_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_TEXT_BASE=0x40000000
CONFIG_CONS_INDEX=0
CONFIG_SYS_TEXT_BASE=0x40300000
# CONFIG_DISPLAY_CPUINFO is not set
2.2.6 spl Support semihost start-up
(1) take arch/arm/lib/semihosting.c in smh_load_file export , That is, remove the static
static int smh_load_file(const char * const name, ulong load_addr,
ulong *end_addr)
{
…
}
(2) take arch/arm/lib/semihosting.c Medium do_smhload The file is modified to only uboot compile , Change it to :
#ifndef CONFIG_SPL_BUILD
static int do_smhload(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) {
}
#endif
(3) stay arch/arm/include/asm/spl.h Of BOOT DEVICE Add pairs to the enumeration semihosting Support for
enum {
…
BOOT_DEVICE_SEMIHOSTING,
BOOT_DEVICE_NONE
};
(4) stay common/spl/ Add files to directory spl_semihosting.c, And add the following :
#include <image.h>
#include <spl.h>
extern int smh_load_file(const char * const name, ulong load_addr,
ulong *end_addr);
static int spl_sh_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
int rc;
ulong uboot_load_addr = 0x40300000, uboot_end_addr;
rc = smh_load_file("u-boot.bin", uboot_load_addr,
&uboot_end_addr);
if (rc < 0) {
if (CONFIG_IS_ENABLED(SHOW_ERRORS) &&
CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT))
printf(SPL_TPL_PROMPT "load file u-boot.bin failed (err=%d)\n",
rc);
else
puts(SPL_TPL_PROMPT "load file u-boot.bin failed\n");
return -1;
}
spl_image->load_addr = uboot_load_addr;
spl_image->entry_point = uboot_load_addr;
spl_image->os = IH_OS_U_BOOT;
return 0;
}
SPL_LOAD_IMAGE_METHOD("SEMIHOSTING", 0, BOOT_DEVICE_SEMIHOSTING, spl_sh_load_image);
appendix : Description of configuration options that affect the compilation directory
(1) Definition CONFIG_SYS_CPU="cpu"
Used to compile arch/<arch>/cpu/<cpu>
(2) Definition CONFIG_SYS_SOC="soc"
Used to compile arch/<arch>/cpu/<cpu>/<soc>
(3) Definition CONFIG_SYS_VENDOR="vendor"
Used to compile board/<vendor>/common/* and board/<vendor>/<board>/*
(4) Definition CONFIG_SYS_BOARD="board"
Used to compile board/<board>/*
If you define CONFIG_SYS_VENDOR, The compiler :board/<vendor>/<board>/*
(5)CONFIG_SYS_CONFIG_NAME="target"
Used to include header files include/configs/<target>.h
边栏推荐
- Avoid mutating a prop directly since the value will be overwritten whenever the parent component
- 关于在云服务器上(这里用腾讯云)安装mysql8.0并使本地可以远程连接的方法
- Verilog design responder [with source code]
- 一度辍学的数学差生,获得今年菲尔兹奖
- STM32入门开发 采用IIC硬件时序读写AT24C08(EEPROM)
- Network foundation (1)
- Go slice comparison
- Poj1821 fence problem solving Report
- How to use cherry pick?
- Verilog 实现数码管显视驱动【附源码】
猜你喜欢
随机推荐
The annual salary of general test is 15W, and the annual salary of test and development is 30w+. What is the difference between the two?
V-for img SRC rendering fails
Vuthink proper installation process
R语言使用quantile函数计算评分值的分位数(20%、40%、60%、80%)、使用逻辑操作符将对应的分位区间(quantile)编码为分类值生成新的字段、strsplit函数将学生的名和姓拆分
R语言使用magick包的image_mosaic函数和image_flatten函数把多张图片堆叠在一起形成堆叠组合图像(Stack layers on top of each other)
基于Retrofit框架的金山API翻译功能案例
通过 Play Integrity API 的 nonce 字段提高应用安全性
The concept, implementation and analysis of binary search tree (BST)
Common SQL statement collation: MySQL
对比学习之 Unsupervised Learning of Visual Features by Contrasting Cluster Assignments
自动化测试框架
oracle常见锁表处理方式
MPX plug-in
When initializing 'float', what is the difference between converting to 'float' and adding 'f' as a suffix?
Learning notes | data Xiaobai uses dataease to make a large data screen
[encapsulation of time format tool functions]
互联网协议
Go slice comparison
There are ways to improve self-discipline and self-control
简单介绍一下闭包及它的一些应用场景