U-Boot usage

    技术2022-05-20  39

    U-Boot源码结构 在顶层目录下有18个子目录,分别存放和管理不同的源程序。这些目录中所要存放的文件有其规则,可以分为3类。 第1类目录与处理器体系结构或者开发板硬件直接相关; 第2类目录是一些通用的函数或者驱动程序; 第3类目录是U-Boot的应用程序、工具或者文档。 平台依赖          board: 存放电路板相关的目录文件,例如:RPXlite(mpc8xx)、smdk2410(arm920t)、sc520_cdp(x86) 等目录 cpu: 存放CPU相关的目录文件,例如:mpc8xx、ppc4xx、arm720t、arm920t、 xscale、i386等目录 lib_ppc: 存放对PowerPC体系结构通用的文件,主要用于实现PowerPC平台通用的函数 lib_arm: 存放对ARM体系结构通用的文件,主要用于实现ARM平台通用的函数 lib_i386: 存放对X86体系结构通用的文件,主要用于实现X86平台通用的函数 通用: include: 头文件和开发板配置文件,所有开发板的配置文件都在configs目录下 common: 通用的多功能函数实现 lib_generic: 通用库函数的实现 Net: 存放网络的程序 Fs: 存放文件系统的程序 Post: 存放上电自检程序 drivers: 通用的设备驱动程序,主要有以太网接口的驱动 Disk: 硬盘接口程序 Rtc: RTC的驱动程序 Dtt: 数字温度测量器或者传感器的驱动 应用例程 examples: 一些独立运行的应用程序的例子,例如helloworld 工具 tools: 存放制作S-Record 或者 U-Boot格式的映像等工具,例如mkimage 文档 Doc: 开发使用文档 U-Boot编译 由顶层目录的Makefile递归调用各级子目录下的Makefile来完成编译,最终将程序链接成U-Boot映像。 Makefile中有对开发板的定义: xxx_config: unconfig @./mkconfg $(@:_config) ... ... 执行 make xxx_config命令,利用./mkconfig脚本生成config.mk配置文件,在include目录下。config.mk文件定义了ARCH, CPU,BOARD,SOC变量,以便平台依赖的目录文件使用 Makefile的编译选项和规则在顶层目录的config.mk中定义。各种体系的通用规则也在改文件中定义。而不同体系结构的规则 分别包含在ppc_config.mk、arm_config.mk、 Makefile缺省的编译目标是all,包括u-boot.srec、u-boot.bin、System.map。u-boot.srec 通过 make xxx_config以及make命令得到: System.map: U-Boot 映像的符号表 u-boot: U-Boot 映像的 ELF 格式 u-boot.bin: U-Boot 映像原始的二进制格式 u-boot.srec: U-Boot 映像的 S-Record 格式 U-Boot的移植 移植 U-Boot 工作就是添加开发板硬件相关的文件、配置选项,然后配置编译。 移植之前要分析U-Boot已经支持的开发板,并选择最相近的开发板。选择的原则是:首先处理器相同,其次处理器体系结构相 同,然后是以太网接口等外围接口。 U-boot移植步骤: 1. 在顶层Makefile中添加开发板配置: xxx_config : unconfig @./mkconfig $(@:_config=) <arch> <cpu> <board> NULL <soc> 2. 创建新目录存放开发板相关代码,并添加文件 board/<board_name>/config.mk board/<board_name>/flash.c board/<board_name>/fs2410.c board/<board_name>/Makefile board/<board_name>/memsetup.S board/<board_name>/u-boot.lds 3. 为开发板添加新的配置文件 include/configs/<board_name>.h 4. 配置开发板 $make <board_name>_config 5. 编译U-Boot $make 6. 添加驱动或者功能选项 实现U-Boot的以太网接口、Flash擦写功能等。 7. 调试U-Boot源代码,直到U-Boot可以在开发板上正常启动 U-Boot启动过程 reset -> cup_init_crit -> memsetup -> relocate -> stack_setup -> start_armboot() -> init_sequence[], ... , getenv() -> main_loop() 程序入口点:从board/<board_name>/u-boot.lds中可以看到,u-boot的程序入口点是_start _start在cpu/<cpu_name>/start.S中,由汇编语言实现。start.S主要完成的工作有: 定义Image的入口点,通常放在ROM(Flash)的0x0地址; 设置异常向量 设置CPU的速度、始终频率及中断控制寄存器 初始化内存控制器 将ROM中的程序复制到RAM中 初始化堆栈 转到RAM中执行( ldr pc) start_armboot()在lib_arm/board.c中,是C语言开始的函数,也是整个启动代码中C语言的主函数。主要完成的工作有: 调用一系列的初始化函数 初始化flash设备 初始化系统内存分配函数 如果目标系统拥有NAND设备,则初始化NAND设备 如果目标系统有显示设备,则初始化该类设备 初始化相关网络设备,填写IP、MAC地址等 进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。 另外,init_sequence[]数组保存基本的初始化函数指针 init_fnc_t *init_sequence[] = { cpu_init, /* 基本的处理器相关配置 -- cpu/arm920t/cpu.c */ board_init, /* 基本的板级相关配置 -- board/smdk2410/smdk2410.c */ interrupt_init, /* 初始化例外处理 -- cpu/arm920t/s3c24x0/interrupt.c */ env_init, /* 初始化环境变量 -- common/cmd_flash.c */ init_baudrate, /* 初始化波特率设置 -- lib_arm/board.c */ serial_init, /* 串口通讯设置 -- cpu/arm920t/s3c24x0/serial.c */ console_init_f, /* 控制台初始化阶段 1 -- common/console.c */ display_banner, /* 打印 u-boot 信息 -- lib_arm/board.c */ dram_init, /* 配置可用的 RAM -- board/smdk2410/smdk2410.c */ display_dram_config, /* 显示 RAM 的配置大小 -- lib_arm/board.c */ NULL, }; U-Boot与内核的关系 通常,U-Boot使用go和bootm直接引导内核映像启动。U-Boot 与内核的关系主要是内核启动过程中参数的传递。 go 命令调用 do_go()函数,跳转到某个地址执行的。如果在这个地址准备好了自引导的内核映像,就可以启动了。尽管 go 命令可以带变参,实际使用时一般不用来传递参数。 /* common/cmd_boot.c */ int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) bootm 命令调用 do_bootm 函数。这个函数专门用来引导各种操作系统映像,可以支持引导 Linux、vxWorks、QNX 等操作系统。 /* common/cmd_bootm.c */ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) do_bootm_linux()函数是专门引导 Linux 映像的函数,它还可以处理 ramdisk 文件系统的映像。这里引导的内核映像和 ramdisk 映像,必须是 U-Boot 格式的。U-Boot 格式的映像可以通过 mkimage 工具来转换,其中包含了 U-Boot 可以识别的符号。 /* lib_arm/armlinux.c */ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],ulong addr, ulong *len_ptr, int verify) 烧写U-Boot到Flash 对于可以取下来的EPROM或Flash,可通过编程器直接烧写 对于不能取下来的贴片Flash,可通过处理器的调试接口,直接对板上的Flash编程: 标准的处理器调试接口有BDM,JTAG和EJTAG 3种。 BDM(Background Debug Mode)主要支持PowerPC8xx系列处理器 JTAG(Joint Test Action Group)支持大多数比较复杂的器件,如ARM,DSP,FPGA等 EJTAG(Extended JTAG)主要支持MIPS处理器 U-Boot常用命令 autoscr - run script from memory base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation dhcp - invoke DHCP client to obtain IP/boot params echo - echo args to console erase - erase FLASH memory flinfo - print FLASH memory information go - start application at address 'addr' help - print online help iminfo - print header information for application image imls - list all images found in flash itest - return true/false on integer compare loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) printenv - print environment variables protect - enable or disable FLASH write protection rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol version - print monitor version U-Boot环境变量 可以通过pringenv命令打印环境变量: bootdelay: 定义执行自动启动的等候秒数 baudrate: 定义串口控制台的波特率 netmask: 定义以太网接口的掩码 ethaddr: 定义以太网接口的 MAC 地址 bootfile: 定义缺省的下载文件 bootargs: 定义传递给 Linux 内核的命令行参数 bootcmd: 定义自动启动时执行的几条命令 serverip: 定义 tftp 服务器端的 IP 地址 ipaddr: 定义本地的 IP 地址 stdin: 定义标准输入设备,一般是串口 stdout: 定义标准输出设备,一般是串口 stderr: 定义标准出错信息输出设备,一般是串口

    最新回复(0)