当前位置:网站首页>[u-boot] main line analysis of u-boot operation [02] - board_ init_ f
[u-boot] main line analysis of u-boot operation [02] - board_ init_ f
2022-07-21 06:03:00 【iriczhao】
《u-boot Operation mainline analysis 【02】—board_init_f》
List of articles
- 1、setup_mon_len
- 2、fdtdec_setup
- 3、trace_early_init
- 4、initf_malloc
- 5、log_init
- 6、initf_bootstate
- 7、event_init
- 8、bloblist_init
- 9、console_record_init
- 10、arch_cpu_init
- 11、mach_cpu_init
- 12、initf_dm
- 13、arch_cpu_init_dm
- 14、mark_bootstage
- 15、timer_init
- 16、get_clocks
- 17、env_init
- 18、 Console serial port initialization
- 19、fdtdec_prepare_fdt
- 20、display_options
- 21、display_text_info
- 22、print_cpuinfo
- 23、show_board_info
- 24、 Watchdog operation
- 25、init_func_i2c
- 26、init_func_spi
- 27、 Print out DRAM Relevant information
- 28、post_init_f
- 29、 Relocation code
- 29.1、setup_dest_addr
- 29.2、reserve_uboot
- 29.3、reserve_prom
- 29.4、reserve_logbuffer
- 29.5、reserve_pram
- 29.6、reserve_round_4k
- 29.7、reserve_global_data
- 29.8、reserve_fdt
- 29.9、reserve_arch
- 29.10、reserve_stacks
- 29.11、dram_init_banksize
- 29.12、show_dram_config
- 29.13、setup_bdinfo
- 29.14、display_new_sp
- 29.15、reloc_bootstage
- 29.16、reloc_bloblist
- 29.17、setup_reloc
- 30、clear_bss
We from 《u-boot Operation mainline analysis 【01】—_main》 In the article , Already know , stay u-boot In the main starting line , Will call two very important functions :
board_init_f()
and board_init_r()
. Suppose here with ARM32 Architecture, for example , Then there will be arch/arm/lib/crt0.S In the path file _main
Called under the assembly tag : ENTRY(_main)
/* Omit some assembly code */
mov r0, #0
bl board_init_f
/* Omit some assembly code */
ENDPROC(_main)
In the above code , Use mov take 0 Move to r0 In the register , And then use bl board_init_f
The statement calls board_init_f Function and will 0 Pass as an argument to this function .
Next , Let's analyze board_init_f function , The function is defined in /common/board_f.c In file :
void board_init_f(ulong boot_flags)
{
gd->flags = boot_flags;
gd->have_console = 0;
if (initcall_run_list(init_sequence_f))
hang();
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ !defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64) && \ !defined(CONFIG_ARC)
/* NOTREACHED - jump_to_copy() does not return */
hang();
#endif
}
As can be seen from the above code , Set at the beginning of the function gd Of flags and have_console Parameter values for 0, And then call initcall_run_list function , And will init_sequence_f Parameters are passed to the function ,init_sequence_f Is an array of function pointers , The elements in the array are function names .initcall_run_list()
The function is defined as follows :
static inline int initcall_run_list(const init_fnc_t init_sequence[])
{
const init_fnc_t *init_fnc_ptr;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
unsigned long reloc_ofs = 0;
int ret;
/* * Sandbox is relocated by the OS, so symbols always appear at * the relocated address. */
if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC))
reloc_ofs = gd->reloc_off;
#ifdef CONFIG_EFI_APP
reloc_ofs = (unsigned long)image_base;
#endif
if (reloc_ofs)
debug("initcall: %p (relocated to %p)\n",
(char *)*init_fnc_ptr - reloc_ofs,
(char *)*init_fnc_ptr);
else
debug("initcall: %p\n", (char *)*init_fnc_ptr - reloc_ofs);
ret = (*init_fnc_ptr)();
if (ret) {
printf("initcall sequence %p failed at call %p (err=%d)\n",
init_sequence,
(char *)*init_fnc_ptr - reloc_ofs, ret);
return -1;
}
}
return 0;
}
In the above code , Use for Loop structure , Loop the function pointer array in turn , And use the function pointer to call and execute the corresponding function :
ret = (*init_fnc_ptr)();
Sum up ,u-boot Start main line ——board_init_f The essence is :init_sequence_f The call of function pointer elements in this function pointer array . These functions will be analyzed one by one below .
The following functions will be in 【init_sequence_f】 Expand the contents of the function pointer array , The order is consistent with the order of the elements placed in the array .
1、setup_mon_len
The function is defined as follows :
static int setup_mon_len(void)
{
#if defined(__ARM__) || defined(__MICROBLAZE__)
gd->mon_len = (ulong)&__bss_end - (ulong)_start;
#elif defined(CONFIG_SANDBOX)
gd->mon_len = 0;
#elif defined(CONFIG_EFI_APP)
gd->mon_len = (ulong)&_end - (ulong)_init;
#elif defined(CONFIG_NIOS2) || defined(CONFIG_XTENSA)
gd->mon_len = CONFIG_SYS_MONITOR_LEN;
#elif defined(CONFIG_SH) || defined(CONFIG_RISCV)
gd->mon_len = (ulong)(&__bss_end) - (ulong)(&_start);
#elif defined(CONFIG_SYS_MONITOR_BASE)
/* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
#endif
return 0;
}
In the above code , If it is ARM framework , The function content changes to :
gd->mon_len = (ulong)&__bss_end - (ulong)_start;
according to __bss_end and _start, To calculate the u-boot Size , And assign the value to gd->mon_len
.
2、fdtdec_setup
In the open CONFIG_OF_CONTROL Macro definition ,fdtdec_setup The function will open . This function is used to start u-boot Device tree related descriptor support , It's defined in (/lib/fdtdec.c) In file .
3、trace_early_init
This function is defining CONFIG_TRACE_EARLY Under the premise of macro , Used to initialize the tracking system , In order to u-boot Early tracking .
4、initf_malloc
initf_malloc The function is used to set the... Before relocation malloc()
, For use , for example :malloc_limit(malloc Memory pool size ). Defined in the file common/dlmalloc.c In file .
5、log_init
log_init The function is used to start u-boot Of log System , Prepare for subsequent use . Functions are defined in the file common/log.c In file .
6、initf_bootstate
This function is used to record board_init_f() Start state of ( stay arch_cpu_init()
After the function ):
static int initf_bootstage(void)
{
bool from_spl = IS_ENABLED(CONFIG_SPL_BOOTSTAGE) &&
IS_ENABLED(CONFIG_BOOTSTAGE_STASH);
int ret;
ret = bootstage_init(!from_spl);
if (ret)
return ret;
if (from_spl) {
const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE);
if (ret && ret != -ENOENT) {
debug("Failed to unstash bootstage: err=%d\n", ret);
return ret;
}
}
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
return 0;
}
7、event_init
event_init The function is used to start Dynamic events , Initialize dynamic event initialization list , In order to add elements when necessary . The definition is as follows :
int event_init(void)
{
struct event_state *state = gd_event_state();
INIT_LIST_HEAD(&state->spy_head);
return 0;
}
8、bloblist_init
When on CONFIG_BLOBLIST Start the function under the premise of macro definition , Functions are defined in the file common/bloblist.c In file , The function of this function is : Using a single bloblist initialization bloblist System .
9、console_record_init
The function is in CONFIG_CONSOLE_RECORD Open when open , Record for starting the console buffer.
10、arch_cpu_init
For... Based on a specific architecture cpu Initialization operation . This function is a weak function , If the code under a specific architecture does not re implement this function , Then this function will do nothing .
11、mach_cpu_init
SoC/ Machine related CPU Set up , And arch_cpu_init
Function similar to , This function is a weak function , If the code under a specific architecture does not re implement this function , Then this function will do nothing .
12、initf_dm
This function is the initialization operation of the driving model , The definition is as follows :
static int initf_dm(void)
{
#if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN)
int ret;
// Initialize the drive model structure and scan the device
ret = dm_init_and_scan(true);
if (ret)
return ret;
#endif
#ifdef CONFIG_TIMER_EARLY
// Initialization timer is used to hold time
ret = dm_timer_init();
if (ret)
return ret;
#endif
return 0;
}
13、arch_cpu_init_dm
Initialize after obtaining the drive model CPU.
14、mark_bootstage
This function is used to record board_init_f()
The start-up phase of ( stay arch_cpu_init Call after function )
15、timer_init
This function is related to the specific architecture and processor chip , There are many different implementations . be used for : Initialize the timer , Use this timer for u-boot Provide time parameters .
16、get_clocks
This function is used to obtain the clock parameter value . This function is implemented by register operation , And pass gd->arch Fill in struct arch_global_data
Data in structure , So as to obtain the clock information of the corresponding chip .
17、env_init
This function can be defined in many forms , This function is used to store environment initialization of environment variables , In practical use ,env There are many storage forms . stay /common/env_xxx.c Almost all of them will realize env_init()
function , Compiling u-boot When , One of them will be selected for compilation u-boot. The implementation essence of this function is : Set up gd Member variables of env_addr, That is, the storage address of the environment variable . Varied env_init The definition is shown in the figure below :
18、 Console serial port initialization
18.1 、init_baud_rate
Used to initialize baud rate , According to the variable baudrate To initialize the gd->baudrate. The definition is as follows :
static int init_baud_rate(void)
{
gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
return 0;
}
18.2、serial_init
This function is used to initialize the serial port , It's defined in /drivers/serial/serial.c
perhaps /drivers/serial/serial-uclass.c
in
18.3、console_init_f,
Console initialization in phase one , It's defined in /common/console.c in , Call before relocation — Use serial functions .
19、fdtdec_prepare_fdt
The function is defined in /lib/fdtdec.h
In file , The function of this function is : Make sure there is an effective fdt To control U-Boot. The function is defined as follows :
int fdtdec_prepare_fdt(void)
{
if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) ||
fdt_check_header(gd->fdt_blob)) {
#ifdef CONFIG_SPL_BUILD
puts("Missing DTB\n");
#else
puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
# ifdef DEBUG
if (gd->fdt_blob) {
printf("fdt_blob=%p\n", gd->fdt_blob);
print_buffer((ulong)gd->fdt_blob, gd->fdt_blob, 4,
32, 0);
}
# endif
#endif
return -1;
}
return 0;
}
20、display_options
This function is used to display some information about u-boot Some information . It's defined in /lib/display_options.c In file :
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;
}
21、display_text_info
If open u-boot Of DEBUG function , Will be output text_base,bss_start,bss_end Etc . The function is defined as follows :
static int display_text_info(void)
{
#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_EFI_APP)
ulong bss_start, bss_end, text_base;
bss_start = (ulong)&__bss_start;
bss_end = (ulong)&__bss_end;
#ifdef CONFIG_SYS_TEXT_BASE
text_base = CONFIG_SYS_TEXT_BASE;
#else
text_base = CONFIG_SYS_MONITOR_BASE;
#endif
debug("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
text_base, bss_start, bss_end);
#endif
#ifdef CONFIG_USE_IRQ
debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif
return 0;
}
22、print_cpuinfo
Print out cpu Relevant information , This function is an architecture related function , There are many implementations of this function under different architectures or chips . In compiling build u-boot When , Will compile an implementation into u-boot In the mirror .
23、show_board_info
This function is used to display the information of the hardware board , It's defined in /common/board_info.c In file :
int show_board_info(void)
{
#if defined(CONFIG_OF_CONTROL) && !defined(CONFIG_CUSTOM_BOARDINFO)
DECLARE_GLOBAL_DATA_PTR;
const char *model;
model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
if (model)
printf("Model: %s\n", model);
#endif
return checkboard();
}
In the above code , Would call checkboard() This function , This function is an architecture related function !
24、 Watchdog operation
INIT_FUNC_WATCHDOG_INIT: This function is used to initialize the watchdog .
INIT_FUNC_WATCHDOG_RESET : This function is used to reset the watchdog .
25、init_func_i2c
This function is used to initialize i2c, The definition is as follows :
static int init_func_i2c(void)
{
puts("I2C: ");
#ifdef CONFIG_SYS_I2C
i2c_init_all();
#else
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
puts("ready\n");
return 0;
}
26、init_func_spi
This function is used for spi, The definition is as follows :
static int init_func_spi(void)
{
puts("SPI: ");
spi_init();
puts("ready\n");
return 0;
}
27、 Print out DRAM Relevant information
27.1、announce_dram_init
This function is used to print out "DRAM: " Information :
static int announce_dram_init(void)
{
puts("DRAM: ");
return 0;
}
27.2、dram_init
This function is not used to initialize DRAM Of , Just settings gd->sram_sized Value , And set the parameters Count Value print out . The function is defined in /board The directory is related to specific hardware boards .
28、post_init_f
This function is used to complete some tests , initialization gd->post_init_f_time
, The function is defined in /post/post.c In file .
29、 Relocation code
The code runs here , It has been established DRAM Mapping and are already working , We can reposition the code and continue from DRAM function , stay RAM At the end of it is ( From top to bottom ) Reserve memory :
(1)U-Boot and Linux Areas that will not be touched ( Optional ).
(2) kernel logbuffer Area
(3) The protected RAM
(4)LCD Frame buffer (framebuffer)
(5) The area where the monitoring code is stored .
(6) Board level information structure .
There are some reserved operations associated with specific macro definitions , The following code :
#if defined(CONFIG_BLACKFIN)
/* Blackfin u-boot monitor should be on top of the ram */
reserve_uboot,
#endif
#if defined(CONFIG_SPARC)
reserve_prom,
#endif
#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
reserve_logbuffer,
#endif
#ifdef CONFIG_PRAM
reserve_pram,
#endif
reserve_round_4k,
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \ defined(CONFIG_ARM)
reserve_mmu,
#endif
#ifdef CONFIG_DM_VIDEO
reserve_video,
#else
# ifdef CONFIG_LCD
reserve_lcd,
# endif
/* TODO: Why the dependency on CONFIG_8xx? */
# if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \ !defined(CONFIG_ARM) && !defined(CONFIG_X86) && \ !defined(CONFIG_BLACKFIN) && !defined(CONFIG_M68K)
reserve_legacy_video,
# endif
#endif /* CONFIG_DM_VIDEO */
reserve_trace,
#if !defined(CONFIG_BLACKFIN)
reserve_uboot,
#endif
#ifndef CONFIG_SPL_BUILD
reserve_malloc,
reserve_board,
#endif
29.1、setup_dest_addr
Start destination address , The function is defined as follows :
static int setup_dest_addr(void)
{
debug("Monitor len: %08lX\n", gd->mon_len);
/* * Ram is setup, size stored in gd !! */
debug("Ram size: %08lX\n", (ulong)gd->ram_size);
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
/* Reserve memory for secure MMU tables, and/or security monitor */
gd->ram_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
/* * Record secure memory location. Need recalcuate if memory splits * into banks, or the ram base is not zero. */
gd->secure_ram = gd->ram_size;
#endif
/* * Subtract specified amount of memory to hide so that it won't * get "touched" at all by U-Boot. By fixing up gd->ram_size * the Linux kernel should now get passed the now "corrected" * memory size and won't touch it either. This has been used * by arch/powerpc exclusively. Now ARMv8 takes advantage of * thie mechanism. If memory is split into banks, addresses * need to be calculated. */
gd->ram_size = board_reserve_ram_top(gd->ram_size);
#ifdef CONFIG_SYS_SDRAM_BASE
gd->ram_top = CONFIG_SYS_SDRAM_BASE;
#endif
gd->ram_top += get_effective_memsize();
gd->ram_top = board_get_usable_ram_top(gd->mon_len);
gd->relocaddr = gd->ram_top;
debug("Ram top: %08lX\n", (ulong)gd->ram_top);
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
/* * We need to make sure the location we intend to put secondary core * boot code is reserved and not used by any part of u-boot */
if (gd->relocaddr > determine_mp_bootpg(NULL)) {
gd->relocaddr = determine_mp_bootpg(NULL);
debug("Reserving MP boot page to %08lx\n", gd->relocaddr);
}
#endif
return 0;
}
29.2、reserve_uboot
reserve u-boot Space , The function is defined as follows :
static int reserve_uboot(void)
{
/* * reserve memory for U-Boot code, data & bss * round down to next 4 kB limit */
gd->relocaddr -= gd->mon_len;
gd->relocaddr &= ~(4096 - 1);
#ifdef CONFIG_E500
/* round down to next 64 kB limit so that IVPR stays aligned */
gd->relocaddr &= ~(65536 - 1);
#endif
debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10,
gd->relocaddr);
gd->start_addr_sp = gd->relocaddr;
return 0;
}
29.3、reserve_prom
The function is defined as follows :
static int reserve_prom(void)
{
/* defined in arch/sparc/cpu/leon?/prom.c */
extern void *__prom_start_reloc;
int size = 8192; /* page table = 2k, prom = 6k */
gd->relocaddr -= size;
__prom_start_reloc = map_sysmem(gd->relocaddr + 2048, size - 2048);
debug("Reserving %dk for PROM and page table at %08lx\n", size,
gd->relocaddr);
return 0;
}
29.4、reserve_logbuffer
This function is used to reserve the kernel log Of buffer Area , The function is defined as follows :
static int reserve_logbuffer(void)
{
/* reserve kernel log buffer */
gd->relocaddr -= LOGBUFF_RESERVE;
debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
gd->relocaddr);
return 0;
}
29.5、reserve_pram
This function is used to reserve protected RAM Area , The definition is as follows :
static int reserve_pram(void)
{
ulong reg;
reg = getenv_ulong("pram", 10, CONFIG_PRAM);
gd->relocaddr -= (reg << 10); /* size is in kB */
debug("Reserving %ldk for protected RAM at %08lx\n", reg,
gd->relocaddr);
return 0;
}
29.6、reserve_round_4k
This function is used to round the memory pointer to the next 4 kB Limit . The definition is as follows :
static int reserve_round_4k(void)
{
gd->relocaddr &= ~(4096 - 1);
return 0;
}
29.7、reserve_global_data
This function is used to global_data Reserve space , The function is defined as follows :
static int reserve_global_data(void)
{
gd->start_addr_sp = reserve_stack_aligned(sizeof(gd_t));
gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));
debug("Reserving %zu Bytes for Global Data at: %08lx\n",
sizeof(gd_t), gd->start_addr_sp);
return 0;
}
The initial address of the stack pointer will be set in the above code gd->start_addr_sp, Then a new one will be set global_data Object pointer .
29.8、reserve_fdt
Reserve equipment tree , The function is defined as follows :
static int reserve_fdt(void)
{
if (!IS_ENABLED(CONFIG_OF_EMBED)) {
If the device tree is directly above the image , Then it must be relocated . If it is embedded in data section, Then it will be relocated with other data .
if (gd->fdt_blob) {
gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32);
gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
debug("Reserving %lu Bytes for FDT at: %08lx\n",
gd->fdt_size, gd->start_addr_sp);
}
}
return 0;
}
This function is used to reserve the device tree .
29.9、reserve_arch
Architecture related memory reservation .
29.10、reserve_stacks
This function is used to ensure that the stack pointer is 16 Byte alignment . At the same time call arch_reserve_stacks()
Function to modify the code of a specific architecture gd->start_addr_sp
and gd->irq_sp
. The definition is as follows :
static int reserve_stacks(void)
{
/* make stack pointer 16-byte aligned */
gd->start_addr_sp = reserve_stack_aligned(16);
/* * let the architecture-specific code tailor gd->start_addr_sp and * gd->irq_sp */
return arch_reserve_stacks();
}
29.11、dram_init_banksize
stay /common/board_f.c There is a weak definition of this function in the file , This function is related to the specific architecture , Each architecture has its own definition . Function operations are mostly similar , The following code snippet :
__weak int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = gd->ram_base;
gd->bd->bi_dram[0].size = get_effective_memsize();
return 0;
}
Set up gd->bd->bi_dram[0].start
Start address and gd->bd->bi_dram[0].size
size .
29.12、show_dram_config
This function is used to print dram Configuration information , The definition is as follows :
static int show_dram_config(void)
{
unsigned long long size;
int i;
debug("\nRAM Configuration:\n");
for (i = size = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
size += gd->bd->bi_dram[i].size;
debug("Bank #%d: %llx ", i,
(unsigned long long)(gd->bd->bi_dram[i].start));
#ifdef DEBUG
print_size(gd->bd->bi_dram[i].size, "\n");
#endif
}
debug("\nDRAM: ");
print_size(size, "");
board_add_ram_info(0);
putc('\n');
return 0;
}
The above code is based on CONFIG_NR_DRAM_BANKS
The value of is accumulated by this , Finally, print the accumulated result .
29.13、setup_bdinfo
This function is used to set gd Medium bd Data parameters under structure :SRAM Start address of (bi_sramstart)、SRAM Size (bi_sramsize). Finally, functions independent of the specific architecture will be called :arch_setup_bdinfo. The function is defined as follows :
int setup_bdinfo(void)
{
struct bd_info *bd = gd->bd;
if (IS_ENABLED(CONFIG_SYS_HAS_SRAM)) {
bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM */
bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */
}
#ifdef CONFIG_MACH_TYPE
bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
#endif
return arch_setup_bdinfo();
}
29.14、display_new_sp
When debugging is on , A new stack pointer will be printed , The function is set as follows :
static int display_new_sp(void)
{
debug("New Stack Pointer is: %08lx\n", gd->start_addr_sp);
return 0;
}
29.15、reloc_bootstage
This function is used to relocate the existing records in the startup phase , The definition is as follows :
static int reloc_bootstage(void)
{
#ifdef CONFIG_BOOTSTAGE
if (gd->flags & GD_FLG_SKIP_RELOC)
return 0;
if (gd->new_bootstage) {
int size = bootstage_get_size();
debug("Copying bootstage from %p to %p, size %x\n",
gd->bootstage, gd->new_bootstage, size);
memcpy(gd->new_bootstage, gd->bootstage, size);
gd->bootstage = gd->new_bootstage;
bootstage_relocate();
}
#endif
return 0;
}
The above function will use memcpy Perform memory copy operation .
29.16、reloc_bloblist
The function is used to reposition bloblist, The definition is as follows :
static int reloc_bloblist(void)
{
#ifdef CONFIG_BLOBLIST
/* * Relocate only if we are supposed to send it */
if ((gd->flags & GD_FLG_SKIP_RELOC) &&
CONFIG_BLOBLIST_SIZE == CONFIG_BLOBLIST_SIZE_RELOC) {
debug("Not relocating bloblist\n");
return 0;
}
if (gd->new_bloblist) {
int size = CONFIG_BLOBLIST_SIZE;
debug("Copying bloblist from %p to %p, size %x\n",
gd->bloblist, gd->new_bloblist, size);
bloblist_reloc(gd->new_bloblist, CONFIG_BLOBLIST_SIZE_RELOC,
gd->bloblist, size);
gd->bloblist = gd->new_bloblist;
}
#endif
return 0;
}
29.17、setup_reloc
This function will start relocation according to the start relocation flag , The function is defined as follows :
static int setup_reloc(void)
{
if (!(gd->flags & GD_FLG_SKIP_RELOC)) {
#ifdef CONFIG_SYS_TEXT_BASE
#ifdef ARM
gd->reloc_off = gd->relocaddr - (unsigned long)__image_copy_start;
#elif defined(CONFIG_MICROBLAZE)
gd->reloc_off = gd->relocaddr - (u32)_start;
#elif defined(CONFIG_M68K)
/* * On all ColdFire arch cpu, monitor code starts always * just after the default vector table location, so at 0x400 */
gd->reloc_off = gd->relocaddr - (CONFIG_SYS_TEXT_BASE + 0x400);
#elif !defined(CONFIG_SANDBOX)
gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
#endif
#endif
}
// Execute memory copy
memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
if (gd->flags & GD_FLG_SKIP_RELOC) {
debug("Skipping relocation due to flag\n");
} else {
debug("Relocation Offset is: %08lx\n", gd->reloc_off);
debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n",
gd->relocaddr, (ulong)map_to_sysmem(gd->new_gd),
gd->start_addr_sp);
}
return 0;
}
30、clear_bss
This function definition is used to clear BSS Paragraph content . This is a weak function definition , There is nothing in it . The code under the specific architecture can implement this function to clear bss Related content . about ARM In terms of Architecture , There is no corresponding implementation , So the function does nothing !
边栏推荐
猜你喜欢
Kettle [practice 03] details of difficulties in classification, analysis and warehousing of KML type files in Shuijing micrograph (complete process example cloud resource sharing: including sql+kjb+kt
Try to understand the essence of low code platform design from another angle
SPSS kmeans clustering practice
程序中提升几毫秒、节省几 kB 的内存有必要吗?
Unity learning notes conversion between plane pixel coordinates of spherical panorama and coordinates on three-dimensional coordinate system
Winform中实现窗体控件适配(自适应窗体)布局_通过C#代码方式
数商云精细化工行业管理平台一体化信息化解决方案
APK打包流程
煤炭行业供应链集采系统:数字化推进煤炭产业转型升级
Redis-String类型
随机推荐
探索者TSSD 2019软件安装包下载及安装教程
Qt | QWidget的一些总结
遥感影像分类工具和webgis的可视化应用
Cloudreve-部署一个属于自己的公有云云盘(宝塔安装方法)
What is the role of GIS equipment in land and resources management?
Stm32+dht11 reading temperature and humidity data display
A collection of open source scanners developed by security industry practitioners
短视频直播系统源码
大佬们,这个cdc采集Oracle的数据,为啥number类型采过来就变成了对象?
Redis未授权访问漏洞复现(www.hetianlab.com)
Visual solution of digital twin landing design bridge
Jenkins配置插件界面中文显示「建议收藏」
MATLAB画雷达图(四行代码)
开源轻量级工作流WorkflowCore介绍
UDP 的报文结构和注意事项
幼儿园核酸预约登记小程序实战开发(下篇)
自定义持久层框架MyORMFramework(二)—框架设计
项目启动端口被占用的解决办法
Redis-String类型
暑假打工 2 个 月,让我明白了 Keepalived 高可用的三种路由方案