您好,欢迎来到爱go旅游网。
搜索
您的当前位置:首页kernel如何得到uboot启动信息

kernel如何得到uboot启动信息

来源:爱go旅游网

转载:

一、uboot的的配置和编译

1、配置:make smdk10_config

SRCTREE             := $(CURDIR)

MKCONFIG   := $(SRCTREE)/mkconfig

 

smdk10_config       unconfig

       @$(MKCONFIG) $(@:_config=) arm s3cxx smdk10 samsung s3c10

      

 

mkconfig  smdk10 arm s3cxx smdk10 samsung s3c10

s0        s1       s2  s3       s4      s5       s6

生成如下两个文件:

include/config.mk include/config.h

建立两个软链接文件:

ln -s asm-arm asm

ln -s arch-smdk10 asm-arm/arch

 

2make

   在编译到最后看到了如下一句:

   arm-linux-ld -Bstatic -T /home/uboot/u-boot-10/board/samsung/smdk10/u-boot.lds -Ttext 0xc7e00000 ........

  

二、uboot的源码分析:

       uboot重要的功能如下:

       1)关看门狗

       2)初始化时钟

       3)初始化SDRAM

       4)初始化flash

       5)初始化网卡、usb、串口等

       6)加载内核并且启动内核喂你好你在干麻耶

        u-boot.lds中可以看出“start.o”放在最前面,那么也就注定start.s是整个uboot第一个运行的文件,这样我们就可以从start.s开始分析

       uboot

      

       start.s做了如下的功能:

       1)进入设置为svc

       2)关看门狗

       3)屏蔽中断

       4)初始化

       5)设置stack

       6)时钟

       7)代码重定位,从nand flash  sd ram

       8)bss

       9start_armboot

      

       在进入了start_armboot之后工作流程如下图:

       

最后,从env变量中获取到bootcmd参数(nand read 0xc0008000 0x100000 0x500000;bootm 0xc0008000),执行到了” nand read 0xc0008000 0x100000 0x500000”命令,从nand flash 中将内核到内存中,之后就执行bootm 0xc0008000。最后将会调用如下函数:

do_bootm ->do_bootm_linux->theKernel

1do_bootm:从0x500000中读取UImage的头部,填充到一个全局变量header 中。结构定义为:

[cpp]  
[cpp]  
  1. struct tag_header  
  2.     u32 size;  
  3.     u32 tag;  
  4. };  
  5.   
  6. struct tag  
  7.     struct tag_header hdr;  
  8.     union  
  9.         struct tag_core     core;  
  10.         struct tag_mem32    mem;  
  11.         struct tag_videotext    videotext;  
  12.         struct tag_ramdisk  ramdisk;  
  13.         struct tag_initrd   initrd;  
  14.         struct tag_serialnr serialnr;  
  15.         struct tag_revision revision;  
  16.         struct tag_videolfb videolfb;  
  17.         struct tag_cmdline  cmdline;  
  18.   
  19.           
  20.         struct tag_acorn    acorn;  
  21.   
  22.           
  23.         struct tag_memclk   memclk;  
  24.     u;  
  25. };  

添加这些信息首先调用setup_start_tag (bd),添加完后调用setup_end_tag (bd)

 

[cpp]  
  1. typedef struct bd_info  
  2.     int         bi_baudrate;      
  3.     unsigned long   bi_ip_addr;   
  4.     unsigned char   bi_enetaddr[6];   
  5.     struct environment_s           *bi_env;  
  6.     ulong           bi_arch_number;   
  7.     ulong           bi_boot_params;   
  8.     struct                
  9.      
  10.     ulong start;  
  11.     ulong size;  
  12.               bi_dram[CONFIG_NR_DRAM_BANKS];  
  13. #ifdef CONFIG_HAS_ETH1  
  14.       
  15.     unsigned char   bi_enet1addr[6];  
  16. #endif  
  17. bd_t  
  18.   
  19. typedef struct  global_data  
  20.     bd_t        *bd;  
  21.     unsigned long   flags;  
  22.     unsigned long   baudrate;  
  23.     unsigned long   have_console;     
  24.     unsigned long   reloc_off;    
  25.     unsigned long   env_addr;     
  26.     unsigned long   env_valid;    
  27.     unsigned long   fb_base;      
  28. #ifdef CONFIG_VFD  
  29.     unsigned char   vfd_type;     
  30. #endif  
  31. #if 0  
  32.     unsigned long   cpu_clk;      
  33.     unsigned long   bus_clk;  
  34.     unsigned long   ram_size;     
  35.     unsigned long   reset_status;     
  36. #endif  
  37.     void        **jt;         
  38. gd_t;  

3、有了上述信息和配置后我们就可以开始启动内核,调用

theKernel (0, bd->bi_arch_number, bd->bi_boot_params),之后我们的linux内核就开始工作了,uboot的使命就完成了!

 

以下参考:

 

在 uboot/board/davinci/dm365evm的board_init函数中
 uboot中:

机器码:
gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_DM365_EVM
而#define MACH_TYPE_DAVINCI_DM365_EVM  1939 定义在arch\arm\include\asm\Mach-types.h中

 

 kernel中:
需对应内核的linux/arch/arm/mach-davinci/Board-dm365-evm.c中一行代码
MACHINE_START(DAVINCI_DM365_EVM, "DaVinci_DM365x_EVM")
而DAVINCI_DM365_EVM定义在linux/asm

#define DAVINCI_DM365_EVM 1939

 

注:

在内核自解压完成以后内核会首先会进入 bl      __lookup_machine_type函数(在arch/arm/kernel/head.S中),检查machine_type是否匹配,如果不匹配会跳入__error_a函数(在arch/arm/kernel/head-common.S中),导致启动失败

 


②指定参数位置:

在uboot:

 uboot/board/davinci/dm365evm 的board_init函数中

gd->bd->bi_boot_params=PHYS_SDRAM_1+0x100  //

#definde PHYS_SDRAM_1 0x80000000 定义在include\configs\Davin_dm365evm.h

 

所以即使uboot中设置    gd->bd->bi_boot_params = 0x30000000或 0x30000200或 0x300000300(或许设置一个空闲的内存区就可以)
而内核的.boot_params    = S3C2410_SDRAM_PA + 0x100,(就用不到了)
也能顺利启动内核,已试过

在试验中发现uboot中设置gd->bd->bi_boot_params=0或将gd->bd->bi_boot_params注释掉,都未能顺利启动内核。貌似在uboot必须为gd->bd->bi_boot_params指定一个值才行,而linux的.boot_params 始终都没有用到。


gd是一个全局结构体指针,用于uboot中各个文件中重要的参数传递,其成员见
看一下uboot在sdram 0x30000100处给内核传递了什么东东,见
参考嵌入式Linux应用开发完全手册ch15.1 p243

 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igat.cn 版权所有 赣ICP备2024042791号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务