日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

5-global_data介绍

發布時間:2025/3/21 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 5-global_data介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[uboot] (番外篇)global_data介紹
2016年11月02日 22:05:49閱讀數:2266

以下例子都以project X項目tiny210(s5pv210平臺,armv7架構)為例

[uboot] uboot流程系列:?
[project X] tiny210(s5pv210)上電啟動流程(BL0-BL2)?
[uboot] (第一章)uboot流程——概述?
[uboot] (第二章)uboot流程——uboot-spl編譯流程

===================================================================================

一、global_data功能

1、global_data存在的意義

在某些情況下,uboot是在某些只讀存儲器上運行,比如ROM、nor flash等等。?
在uboot被重定向到RAM(可讀可寫)之前,我們都無法寫入數據,更無法通過全局變量來傳遞數據。?
而global_data則是為了解決這個問題。?
這里順便一下,后續的uboot的relocation操作,也就是uboot的重定向操作,最主要的目的也是為了解決這個問題,后續會專門說明。

2、 global_data簡單介紹

global_data又稱之為GD.?
簡單地說,uboot把global_data放在RAM區,并且使用global_data來存儲全局數據。由此來解決上述場景中無法使用全局變量的問題。

二、global_data數據結構

1、數據結構說明

global_data數據結構結構體定義為struct global_data,被typedef為gd_t。?
也就是說可以直接通過struct global_data或者gd_t來進行聲明。?
struct global_data定義如下(過濾掉一些被宏定義包含的部分):?
include/asm-generic/global_data.h

typedef struct global_data {bd_t *bd;unsigned long flags;unsigned int baudrate;unsigned long cpu_clk; /* CPU clock in Hz! */unsigned long bus_clk;/* We cannot bracket this with CONFIG_PCI due to mpc5xxx */unsigned long pci_clk;unsigned long mem_clk;unsigned long have_console; /* serial_init() was called */unsigned long env_addr; /* Address of Environment struct */unsigned long env_valid; /* Checksum of Environment valid? */unsigned long ram_top; /* Top address of RAM used by U-Boot */unsigned long relocaddr; /* Start address of U-Boot in RAM */phys_size_t ram_size; /* RAM size */unsigned long mon_len; /* monitor len */unsigned long irq_sp; /* irq stack pointer */unsigned long start_addr_sp; /* start_addr_stackpointer */unsigned long reloc_off;struct global_data *new_gd; /* relocated global data */const void *fdt_blob; /* Our device tree, NULL if none */void *new_fdt; /* Relocated FDT */unsigned long fdt_size; /* Space reserved for relocated FDT */struct jt_funcs *jt; /* jump table */char env_buf[32]; /* buffer for getenv() before reloc. */unsigned long timebase_h;unsigned long timebase_l;struct udevice *cur_serial_dev; /* current serial device */struct arch_global_data arch; /* architecture-specific data */} gd_t;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

2、成員說明

  • 重點說明?
    • bd_t *bd:board info數據結構定義,位于文件 include/asm-arm/u-boot.h定義,主要是保存開發板的相關參數。
    • unsigned long env_addr:環境變量的地址。
    • unsigned long ram_top:RAM空間的頂端地址
    • unsigned long relocaddr:UBOOT重定向后地址
    • phys_size_t ram_size:物理ram的size
    • unsigned long irq_sp:中斷的堆棧地址
    • unsigned long start_addr_sp:堆棧地址
    • unsigned long reloc_off:uboot的relocation的偏移
    • struct global_data *new_gd:重定向后的struct global_data結構體
    • const void *fdt_blob:我們設備的dtb地址
    • void *new_fdt:relocation之后的dtb地址
    • unsigned long fdt_size:dtb的長度
    • struct udevice *cur_serial_dev:當前使用的串口設備。

其他成員在后續時候到的時候在進行說明。

三、global_data存放位置以及如何獲取其地址

1、global_data區域設置代碼

(1)首先參考一下分配global_data的代碼。?
common/init/board_init.c

// 這個函數用于給global_data分配空間,在relocation之前調用 // 傳入的參數是頂部地址,但是不一定是要內存頂部的地址,可以自己進行規劃,后面_main函數會說明 ulong board_init_f_alloc_reserve(ulong top) {/* Reserve early malloc arena */ #if defined(CONFIG_SYS_MALLOC_F)top -= CONFIG_SYS_MALLOC_F_LEN; // 先從頂部向下分配一塊CONFIG_SYS_MALLOC_F_LEN大小的空間給early malloc使用 // 關于CONFIG_SYS_MALLOC_F_LEN可以參考README // 這塊內存是用于在relocation前用于給malloc函數提供內存池。 #endif/* LAST : reserve GD (rounded up to a multiple of 16 bytes) */top = rounddown(top-sizeof(struct global_data), 16); // 繼續向下分配sizeof(struct global_data)大小的內存給global_data使用,向下16byte對齊 // 這時候得到的地址就是global_data的地址。return top; // 將top,也就是global_data的地址返回 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

(2)然后看一下初始化global_data區域的代碼。?
common/init/board_init.c?
去除無關代碼的部分

// 這個函數用于對global_data區域進行初始化,也就是清空global_data區域 // 傳入的參數就是global_data的基地址 void board_init_f_init_reserve(ulong base) {struct global_data *gd_ptr;/** clear GD entirely and set it up.* Use gd_ptr, as gd may not be properly set yet.*/gd_ptr = (struct global_data *)base;/* zero the area */memset(gd_ptr, '\0', sizeof(*gd)); // 先通過memset函數對global_data數據結構進行清零/* next alloc will be higher by one GD plus 16-byte alignment */base += roundup(sizeof(struct global_data), 16); // 因為global_data區域是16Byte對齊的,對齊后,后面的地址就是early malloc的內存池的地址,具體參考上述board_init_f_alloc_reserve // 所以這里就獲取了early malloc的內存池的地址/** record early malloc arena start.* Use gd as it is now properly set for all architectures.*/ #if defined(CONFIG_SYS_MALLOC_F)/* go down one 'early malloc arena' */gd->malloc_base = base; // 將內存池的地址寫入到gd->malloc_base中/* next alloc will be higher by one 'early malloc arena' size */base += CONFIG_SYS_MALLOC_F_LEN; //加上CONFIG_SYS_MALLOC_F_LEN,獲取early malloc的內存池的末尾地址,這里并沒有什么作用,是為了以后在early malloc的內存池后面多加一個區域時的修改方便。 #endif }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

(3)arm平臺如何分配global_data區域,并保存其地址。?
代碼如下,去除掉被宏定義包含的無關代碼部分?
arch/arm/lib/crt0.S

ENTRY(_main) /** Set up initial C runtime environment and call board_init_f(0).*/ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) @@ 預設堆棧指針為CONFIG_SYS_INIT_SP_ADDR @@ 在tiny210中初步設置為如下(include/configs/tiny210.h): @@ #define CONFIG_SYS_SDRAM_BASE 0x20000000 @@ #define MEMORY_BASE_ADDRESS CONFIG_SYS_SDRAM_BASE @@ #define PHYS_SDRAM_1 MEMORY_BASE_ADDRESS @@ #define CONFIG_SYS_LOAD_ADDR (PHYS_SDRAM_1 + 0x1000000) /* default load address */ @@ #define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_LOAD_ADDR @@ 最終可以得到CONFIG_SYS_INIT_SP_ADDR是0x3000_0000,也就是uboot relocation的起始地址 @@ 補充一下,DDR的空間是0x2000_0000-0x4000_0000@@ 注意!!!這里只是預設的堆棧地址,而不是最終的堆棧地址!!!bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ @@ 8byte對齊mov r0, spbl board_init_f_alloc_reserve @@ 將sp的值放到r0中,也就是作為board_init_f_alloc_reserve的參數 @@ 返回之后,r0里面存放的是global_data的地址 @@ 注意,同時也是堆棧地址,因為堆棧是向下增長的,所以不必擔心和global_data沖突的問題@@ 綜上,此時r0存放的,既是global_data的地址,也是堆棧的地址mov sp, r0 @@ 把堆棧地址r0存放到sp中/* set up gd here, outside any C code */mov r9, r0 @@ 把global_data的地址存放在r9中 @@ 此時r0存放的還是global_data的地址bl board_init_f_init_reserve @@ 調用board_init_f_init_reserve對global_data進行初始化,r0也就是其參數。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

注意:最終global_data的地址存放在r9中了。

2、global_data內存分布

內存分布如下:?
———————-CONFIG_SYS_LOAD_ADDR —————————–高地址

……………………………..?early malloc 內存池

————————-early malloc 內存池基地址 —————————

…………………………………?global_data區域

—————-global_data基地址(r9), 也是堆棧的起始地址————-

………………………………………堆棧空間

————————————–堆棧結束—————————————-低地址?
注意:最終global_data的地址存放在r9中了。

四、global_data使用方式

1、原理說明

前面我們一直強調了global_data的地址存放在r9中了。?
所以當我們需要global_data的時候,直接從r9寄存器中獲取其地址即可。

uboot中定義了一個宏DECLARE_GLOBAL_DATA_PTR,使我們可以更加簡單地獲取global_data。?
定義如下:?
arch/arm/include/asm/global_data.h

#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9")
  • 1

DECLARE_GLOBAL_DATA_PTR定義了gd_t *gd,并且其地址是r9中的值。?
一旦使用了DECLARE_GLOBAL_DATA_PTR聲明之后,后續就可以直接使用gd變量,也就是global_data了。

2、使用示例

DECLARE_GLOBAL_DATA_PTR定義了gd_t *gd,并且其地址是r9中的值。?
一旦使用了DECLARE_GLOBAL_DATA_PTR聲明之后,后續就可以直接使用gd變量,也就是global_data了。?
簡單例子如下:?
common/board_r.c

DECLARE_GLOBAL_DATA_PTR // 通過DECLARE_GLOBAL_DATA_PTR定義了gd_t *gd // 相當于如下: // #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9")static int initr_reloc(void) {/* tell others: relocation done */gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT; // 直接使用gd變量,也就是uboot的global_data。return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

global_data相對比較簡單,也就不多說了。

總結

以上是生活随笔為你收集整理的5-global_data介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。