【野火Linux移植篇】2-uboot顶层Makefile详解&uboot中的gd结构体

野火这部分内容不如正点原子,本文来自正点原子Linux第31章《Uboot顶层Makefile详解》。

1. uboot 目录结构简介:

最重要的三个文件夹:ABC

1. 文件夹arch:存放关于CPU架构的代码

2. 文件夹board:存放关于特定开发板的代码

3. 文件夹configs:存放uboot的配置,文件的格式为:xxxxx.deconfig,通过编译(make),生成.config文件。

最重要的文件:

1. 文件u-boot.xxx,大多数为编译相关的或者编译生成的目标文件,例如uboot.imx等等。

2.文件Makefile:顶层Makefile,makefile支持嵌套使用,顶层的Makefile会调用下一层的Makefile完成编译工作。

 

2. 在VScode中屏蔽代码:

在.vscode 的settings.json的大括号中加入以下代码:

 1   "search.exclude": {
 2         "**/node_modules": true,
 3         "**/bower_components": true,
 4         
 5         "arch/alpha":true,
 6     },
 7     "files.exclude": {
 8          "**/.git": true,
 9          "**/.svn": true,
10          "**/.hg": true,
11         "**/CVS": true,
12         "**/.DS_Store": true, 
13        
14        "arch/alpha":true, 
      ....... 15 }

注意:

1、 不要在大括号之外加入,因为会被自动清除掉。

2、 冒号前面的是要排除的文件或者文件夹,冒号后面为是否将文件排除, true 表示排除, false 表示不排除。

 

3. Makefile 中的shell 命令案例:

1 HOSTARCH := $(shell uname -m | \
2     sed -e s/i.86/x86/ \
3         -e s/sun4u/sparc64/ \
4         -e s/arm.*/arm/ \
5         -e s/sa110/arm/ \
6         -e s/ppc64/powerpc/ \
7         -e s/ppc/powerpc/ \
8         -e s/macppc/powerpc/\
9         -e s/sh.*/sh/)

这里多处调用了 shell 中的东西:

  • 调用 shell命令“ uname -m”获取架构名称。
  • shell中的“ “|”表示管道,意思是将左边的输出作为右边的输入.

  • sed -e是替换命令,“ sed -e s/i.86/x86/”表示将管道输入的字符串中的“ i.86”替换为 x86”

 

4. make -j 的含义

make -j
用make -j带一个参数,可以把项目在进行并行编译,比如在一台双核的机器上,完全可以用make -j4,让make最多允许4个编译命令同时执行,这样可以更有效的利用CPU资源。
因此make -j16意思即make最多允许16个编译器同时执行,提高编译速度,充分利用本机计算资源。

用make: 40分16秒

用make -j4:23分16秒

用make -j8:22分59秒

由此看来,在多核CPU上,适当的进行并行编译还是可以明显提高编译速度的。但并行的任务不宜太多,一般是以CPU的核心数目的两倍为宜。

不过这个方案不是完全没有cost的,如果项目的Makefile不规范,没有正确的设置好依赖关系,并行编译的结果就是编译不能正常进行。如果依赖关系设置过于保守,则可能本身编译的可并行度就下降了,也不能取得最佳的效果。

参考:
https://blog.csdn.net/a_little_a_day/article/details/78251928
————————————————
版权声明:本文为CSDN博主「翟羽嚄」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mao_hui_fei/article/details/106995062

 

5. uboot中的gd结构体

u-boot中有一个用来保存很多有用信息的全局结构体-gd_t(global data缩写),

其中包括了bd变量,可以说gd_t结构体包括了u-boot中所有重要全局变量。

  •  它是一个内核启动参数,是内核的一个重要的数据结构,它是一个结构体,它保存着内核启动所需要的重要参数,诸如串口波特率,有无控制台,环境变量地址.......
  • 它的值一般要又有bootloader进行传递初始化。

对于ARM平台这个结构体的定义大致如下:

 1 include/asm-arm/global_data.h
 2 
 3 typedef struct global_data {
 4     bd_t  *bd;
 5     unsigned long flags;
 6     unsigned long baudrate;
 7     unsigned long have_console; /* serial_init() was called */
 8     unsigned long reloc_off; /* Relocation Offset */
 9     unsigned long env_addr; /* Address  of Environment struct */
10     unsigned long env_valid; /* Checksum of Environment valid? */
11     unsigned long fb_base; /* base address of frame buffer */
12 
13 #ifdef CONFIG_VFD
14     unsigned char vfd_type; /* display type */
15 #endif
16 
17 #if 0
18     unsigned long cpu_clk; /* CPU clock in Hz!  */
19     unsigned long bus_clk;
20     phys_size_t ram_size; /* RAM size */
21     unsigned long reset_status; /* reset status register at boot */
22 #endif
23     void  **jt;  /* jump table */
24 } gd_t

bd_info (bd_t 类型)在include\asm-arm\u-boot.h 中定义

 1 typedef struct bd_info {
 2     int   bi_baudrate; /* serial console baudrate */
 3     unsigned long bi_ip_addr; /* IP Address */
 4     unsigned char bi_enetaddr[6]; /* Ethernet adress */
 5     struct environment_s        *bi_env;
 6     ulong         bi_arch_number; /* unique id for this board */
 7     ulong         bi_boot_params; /* where this board expects params */
 8     struct    /* RAM configuration */
 9     {
10         ulong start;
11         ulong size;
12     }bi_dram[CONFIG_NR_DRAM_BANKS];
13 #ifdef CONFIG_HAS_ETH1
14     /* second onboard ethernet port */
15     unsigned char   bi_enet1addr[6];
16 #endif
17 } bd_t;

 

在U-boot中使用gd结构之前要用先用宏DECLARE_GLOBAL_DATA_PTR来声明。这个宏的定义如下:

include/asm-arm/global_data.h
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")

从这个宏的定义可以看出,gd是一个保存在ARM的r8寄存器中的gd_t结构体的指针。

对于Linux Kernel,在使用U-boot传递来的gd中的bd时用的是arm_bd,因为:

在arch/arm/kernel/setup.c文件中:

 1 void __init setup_arch(char **cmdline_p)
 2 {
 3     ……
 4     struct tag *tags = (struct tag *)&init_tags;
 5     struct machine_desc *mdesc;
 6     char *from = default_command_line;
 7     void *bd_offset = NULL;
 8     ……
 9     save_bd(bd_offset);
10     ……
11 }
12 
13 save_bd():
14 
15 void __init save_bd(void* addr)
16 {
17     memcpy((char *)__res,
18     (char *)addr,
19     sizeof(bd_t));
20     arm_bd = (bd_t *)__res;
21 }

 

posted @ 2023-05-18 11:03  FBshark  阅读(212)  评论(0编辑  收藏  举报