当前位置:网站首页>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
边栏推荐
猜你喜欢

How to remove addition and subtraction from inputnumber input box

关于测试人生的一站式发展建议

使用MeterSphere让你的测试工作持续高效

一度辍学的数学差生,获得今年菲尔兹奖

学习笔记|数据小白使用DataEase制作数据大屏

高考作文,高频提及科技那些事儿……
![Verilog realizes nixie tube display driver [with source code]](/img/ad/be94912bedc738f4b5f97138db7352.png)
Verilog realizes nixie tube display driver [with source code]

The database synchronization tool dbsync adds support for mongodb and es

PostgreSQL中的表复制

Leetcode - interview question 17.24 maximum submatrix
随机推荐
VIM命令模式与输入模式切换
uniapp 在onLaunch中跳转页面后,点击事件失效解决方法
There are ways to improve self-discipline and self-control
QT implements the delete method of the container
Force buckle 1002 Find common characters
数据库同步工具 DBSync 新增对MongoDB、ES的支持
聊聊SOC启动(七) uboot启动流程三
Rolling puddle Uni_ App (VIII)
科普达人丨一文弄懂什么是云计算?
[untitled]
R language uses image of magick package_ Mosaic functions and images_ The flatten function stacks multiple pictures together to form a stack layers on top of each other
[pyqt] the cellwidget in tablewidget uses signal and slot mechanism
STM32 entry development write DS18B20 temperature sensor driver (read ambient temperature, support cascade)
Using ENSP to do MPLS pseudo wire test
RationalDMIS2022阵列工件测量
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?
The opacity value becomes 1%
对比学习之 Unsupervised Learning of Visual Features by Contrasting Cluster Assignments
Distributed database master-slave configuration (MySQL)
In depth learning autumn recruitment interview questions collection (1)