Uboot之hush方式解析用户命令
uboot代码完全解析

目录
u-boot-1.1.6 之 cpu/arm920t........................................................................2 u-boot 中.lds 连接脚本文件的分析 ...................................................................................................12 分享一篇我总结的 uboot 学习笔记(转) .....................................................................................15 U-BOOT 内存布局及启动过程浅析 ...................................................................................................22 u-boot 中的命令实现 ..........................................................................................................................25 U-BOOT 环境变量实现 ........................................................................................................................28
UBOOT命令详解

常用U-boot命令详解(z)2010-09-30 15:05:52| 分类:学习心得体会|字号订阅U-boot发展到现在,他的命令行模式已经非常接近Linux下的shell了,在我编译的U-boot-2009.11中的命令行模式模式下支持“Tab”键的命令补全和命令的历史记录功能。
而且如果你输入的命令的前几个字符和别的命令不重复,那么你就只需要打这几个字符即可,比如我想看这个U-boot的版本号,命令就是“ version”,但是在所有的命令中没有其他任何一个的命令是由“v”开头的,所以只需要输入“v”即可。
[u-boot@MINI2440]# versionU-Boot 2009.11 ( 4月04 2010 - 12:09:25)[u-boot@MINI2440]# vU-Boot 2009.11 ( 4月04 2010 - 12:09:25)[u-boot@MINI2440]# baseBase Address: 0x00000000[u-boot@MINI2440]# baBase Address: 0x00000000由于U-boot支持的命令实在太多,一个一个细讲不现实,也没有必要。
所以下面我挑一些烧写和引导常用命令介绍一下,其他的命令大家就举一反三,或者“help”吧!(1)获取帮助命令:help 或?功能:查看当前U-boot版本中支持的所有命令。
[u-boot@MINI2440]#help?- alias for'help'askenv - get environment variables from stdinbase - print or set address offsetbdinfo - print Board Info structurebmp - manipulate BMP image databoot - boot default, i.e., run 'bootcmd'bootd - boot default, i.e., run 'bootcmd'bootelf - Boot from an ELF image in memorybootm - boot application image from memorybootp - boot image via network using BOOTP/TFTP protocolbootvx - Boot vxWorks from an ELF imagecmp - memory compareconinfo - print console devices and informationcp - memory copycrc32 - checksum calculationdate - get/set/reset date &timedcache - enable or disable data cachedhcp - boot image via network using DHCP/TFTP protocol echo - echo args to consoleeditenv - edit environment variableeeprom - EEPROM sub-systemerase - erase FLASH memoryexit-exit scriptfatinfo - print information about filesystemfatload - load binary file from a dos filesystemfatls -list files in a directory (default/)flinfo - print FLASH memory informationfsinfo - print information about filesystemsfsload - load binary file from a filesystem imagego - start application at address 'addr'help - print online helpi2c - I2C sub-systemicache - enable or disable instruction cacheiminfo - print header information for application image imls -list all images found in flashimxtract- extract a part of a multi-imageitest -return true/false on integer compareloadb - load binary file over serial line(kermit mode) loads - load S-Record file over serial lineloadx - load binary file over serial line(xmodem mode) loady - load binary file over serial line(ymodem mode) loop - infinite loop on address rangels -list files in a directory (default/)md - memory displaymm - memory modify (auto-incrementing address)mmc - MMC sub-systemmtest - simple RAM read/write testmw - memory write(fill)nand - NAND sub-systemnboot - boot from NAND devicenfs - boot image via network using NFS protocolnm - memory modify (constant address)ping -send ICMP ECHO_REQUEST to network hostprintenv- print environment variablesprotect - enable or disable FLASH write protection rarpboot- boot image via network using RARP/TFTP protocol reginfo - print register informationreset- Perform RESET of the CPUrun - run commands in an environment variablesaveenv - save environment variables to persistent storage setenv -set environment variablesshowvar - print local hushshell variablessleep- delay execution for some timesource - run script from memorytest- minimal test like /bin/shtftpboot- boot image via network using TFTP protocolunzip - unzip a memory regionusb - USB sub-systemusbboot - boot from USB deviceversion - print monitor version以bmp指令为例:Usage:bmp info <imageAddr>- display image infobmp display <imageAddr>[x y]- display image at x,y[u-boot@MINI2440]# h bmbmp - manipulate BMP image dataUsage:bmp info <imageAddr>- display image infobmp display <imageAddr>[x y]- display image at x,y(2)环境变量(environment variables,简称ENV)与相关指令和shell类似,U-Boot也有环境变量。
uboot下执行U_BOOT_CMD定义的命令

uboot下执行U_BOOT_CMD定义的命令今天研究了一下uboot中怎么用do_run()函数来执行定义好的一些命令,发现其实也挺简单的,关键是得把do_run函数的几个参数吃透,这几个参数都是由uboot commmod 的cmd_tbl_s结构体决定的,U_BOOT_CMD的宏定义也取决于它,如下:#defineU_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \ cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}struct cmd_tbl_s {char *name; /* Command Name */int maxargs; /* maximum number of arguments */ int repeatable; /* autorepeat allowed? *//* Implementation function */int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);char *usage; /* Usage message (short) */#ifdef CONFIG_SYS_LONGHELPchar *help; /* Help message (long) */#endif#ifdef CONFIG_AUTO_COMPLETE/* do auto completion on the arguments */int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);#endif}对比两者后很容易就明白了怎样去定义一个uboot下的命令。
接下来看看do_run函数的定义(在../boot/common/main.c 下):#if defined(CONFIG_CMD_RUN)int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){int i;if (argc < 2) { //参数个数小于2则提示重新输入cmd_usage(cmdtp);return 1;}for (i=1; i<argc; ++i) {char *arg;if ((arg = getenv (argv[i])) == NULL) {printf ("## Error: \"%s\" not defined\n", argv[i]);return 1;}#ifndef CONFIG_SYS_HUSH_PARSERif (run_command (arg, flag) == -1){ //调用run_command函数,先查找命令,然后执行命令return 1;}#elseif (parse_string_outer(arg,FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){return 1;}#endif}return 0;}其中第一个参数cmd_tbl_t * cmdtp为Command Table,即命令表参数,该结构体的定义在common.h下,一般设为NULL。
uboot命令

uboot命令U-boot基础现在为Linux开放源代码Bootloader有很多,blob、redboot 及U-BOOT等,其中U-BOOT是目前用来开发嵌入式系统引导代码使用最为广泛的Bootloader。
它支持POWERPC、ARM、MIPS和 X86等处理器,支持嵌入式操作系统有Linux、Vxworks及NetBSD等。
2.1 U-boot源代码目录结构|-- board 平台依赖,存放电路板相关的目录文件|-- common 通用多功能函数的实现|-- cpu 平台依赖,存放cpu相关的目录文件|-- disk 通用。
硬盘接口程序|-- doc 文档|-- drivers 通用的设备驱动程序,如以太网接口驱动|-- dtt|-- examples 应用例子|-- fs 通用存放文件系统的程序|-- include 头文件和开发板配置文件,所有开发板配置文件放在其configs 里|-- lib_arm 平台依赖,存放arm架构通用文件|-- lib_generic 通用的库函数|-- lib_i386 平台依赖,存放x86架构通用文件|-- lib_m68k 平台依赖|-- lib_microblaze 平台依赖|-- lib_mips 平台依赖|-- lib_nios 平台依赖|-- lib_ppc平台依赖,存放ppc架构通用文件|-- net 存放网络的程序|-- post 存放上电自检程序|-- rtc rtc的驱动程序`-- tools 工具详细实例:board:开发板相关的源码,不同的板子对应一个子目录,内部放着主板相关代码。
Board/at91rm9200dk/at91rm9200.c, config.mk, Makefile, flash.c ,u-boot.lds等都和具体开发板的硬件和地址分配有关。
common:与体系结构无关的代码文件,实现了u-boot所有命令,其中内置了一个shell脚本解释器(hush.c, a prototype Bourne shell grammar parser), busybox中也使用了它。
UBOOT源码分析

UBOOT源码分析UBOOT是一种开放源码的引导加载程序。
作为嵌入式系统启动的第一阶段,它负责初始化硬件设备、设置系统环境变量、加载内核镜像以及跳转到内核开始执行。
Uboot的源码是开放的,让我们可以深入了解其内部工作机制和自定义一些功能。
Uboot源码的文件组织结构非常清晰,主要分为三个大类:目录、文件和配置。
其中目录包含了一系列相关的文件,文件存放具体的源码实现代码,配置文件包含了针对特定硬件平台的配置选项。
Uboot源码的核心部分是启动代码,位于arch目录下的CPU架构相关目录中。
不同的CPU架构拥有不同的启动代码实现,如arm、x86等。
这些启动代码主要包括以下几个关键功能:1. 初始化硬件设备:Uboot首先需要初始化硬件设备,例如设置时钟、中断控制器、串口等设备。
这些初始化操作是在启动代码中完成的。
通过查看该部分代码,我们可以了解硬件的初始化过程,以及如何配置相关寄存器。
2. 设置启动参数:Uboot启动参数存储在一个称为"bd_info"的数据结构中,它包含了一些关键的设备和内存信息,例如DRAM大小、Flash 大小等。
这些参数是在启动代码中设置的,以便内核启动时能够正确识别硬件情况。
3. 加载内核镜像:Uboot负责加载内核镜像到内存中,以便内核可以正确执行。
在启动代码中,会通过读取Flash设备或者网络等方式,将内核镜像加载到指定的内存地址处。
加载过程中,可能会进行一些校验和修正操作,以确保内核数据的完整性。
4. 启动内核:在内核镜像加载完成后,Uboot会设置一些寄存器的值,并执行一个汇编指令,跳转到内核开始执行。
此时,Uboot的使命即结束,控制权交由内核处理。
除了启动代码,Uboot源码中还包含了许多其他功能模块,如命令行解析器、存储设备驱动、网络协议栈等。
这些功能模块可以根据需求进行配置和编译,以满足不同平台的需求。
例如,可以通过配置文件选择启用一些功能模块,或者自定义一些新的功能。
uboot cmd机制

uboot cmd机制U-Boot Cmd机制U-Boot是一种开源的引导加载程序,常用于嵌入式系统中。
它提供了一系列的命令行指令(Cmd)来管理和控制系统的启动和运行。
本文将介绍U-Boot Cmd机制,并探讨其在嵌入式系统中的应用。
一、U-Boot Cmd机制的基本原理U-Boot的Cmd机制是通过在源代码中定义一系列的命令函数来实现的。
每个命令函数对应一个特定的命令,当用户在U-Boot的命令行界面输入相应的命令时,U-Boot会调用对应的命令函数来执行相应的操作。
Cmd机制的实现依赖于两个关键的数据结构:cmd_tbl_t和cmd_tbl_list。
cmd_tbl_t是一个结构体,用于存储每个命令的相关信息,如命令名称、命令函数等。
cmd_tbl_list则是一个数组,用于存储所有命令的cmd_tbl_t结构体。
在U-Boot的初始化过程中,所有的命令函数都会被注册到cmd_tbl_list数组中。
当用户输入一个命令时,U-Boot会遍历cmd_tbl_list数组,在数组中找到对应的命令函数,并调用该函数执行相应的操作。
二、U-Boot Cmd机制的使用方法U-Boot的命令行界面提供了丰富的命令,用于管理和控制嵌入式系统的启动和运行。
以下是一些常用的U-Boot命令:1. boot:用于启动系统。
可以指定从哪个设备启动、加载内核镜像和设备树等。
2. printenv:用于打印环境变量。
可以查看当前系统的环境变量设置。
3. setenv:用于设置环境变量。
可以修改系统的环境变量值。
4. saveenv:用于保存环境变量。
将当前环境变量保存到存储设备中,以便下次启动时恢复。
5. ping:用于测试网络连接。
可以向指定的IP地址发送网络请求,测试网络的连通性。
6. tftpboot:用于通过TFTP协议下载文件。
可以从TFTP服务器下载文件到内存中。
7. mmc:用于操作SD卡。
可以查看SD卡的分区、格式化SD卡、读写SD卡中的文件等。
uboot笔记uboot命令分析+实现

uboot笔记uboot命令分析+实现uboot笔记:uboot命令分析+实现Ubootuboot命令分析+实现先贴⼀个重要结构,位于uboot/include/command.h,这个结构代表每个uboot命令struct cmd_tbl_s {char *name; /* Command Name */int maxargs; /* maximum number of arguments*/int repeatable;/* autorepeat allowed? *//* Implementation function */int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);char *usage; /* Usage message (short)简短⽤法信息*/#ifdef CFG_LONGHELPchar *help; /* Help message (long) 长的帮助信息*/#endif#ifdef CONFIG_AUTO_COMPLETE/* do auto completion on the arguments */ int (*complete)(intargc, char *argv[], charlast_char, intmaxv, char *cmdv[]); #endif};typedefstruct cmd_tbl_s cmd_tbl_t;============================================================uboot的第⼀阶段:硬件相关初始化0.reset执⾏arm920t/start.s 过程如下1.设置cpu svc管理模式2.关看门狗中断,mmu等3.设置时钟,sdram,外部总线4.代码重定位,搬运代码,从flash到sdram5.设置栈,bss段清零, bss⽤于未初始化的全局变量和静态变量6.ldr pc, _start_armboot即进⼊uboot启动的第⼆阶段,调⽤c函数start_armboot()从start_armboot开始经过⼀系列外设初始化⽐如falsh_initnand_init...最后循环调⽤mian_loop()main_loop主要流程{1. ⽣成环境变量mtdparts, 调⽤mtdparts_init2. 在启动过程中若⽆空格键按下则boot_zImage,即run_command(getenv("bootcmd"),0)有空格键按下则run_command("menu",0)3. shell过程,读取⽤户的输⼊并执⾏相应的命令{从控制台获得命令,保存在全局变量comsole_buffer中解析命令⾏字符串,分割命令与参数,最后执⾏run_command(...); }}也就是说在mian_loop中,是处理环境变量和控制台⼈机交互,mian_loop调⽤readline ()读取命令⾏到console_buffer,再把console_buffer复制到lastcommand中去,还要设置flag,最后调⽤run_command (lastcommand, flag)函数,run_command (lastcommand, flag)函数中,⾸先定义cmd_tbl_t *cmdtp,再解析命令⾏。
uboot的bootcmd bootargs参数详解

setenv bootargs ‘noinitrd mem=64M console=ttySAC0 root=/dev/nfs nfsroot=192.168.0.3:/nfs ip=192.168.0.5’
上面就是我们经常使用的几种bootargs的组合,老实说,bootargs非常非常的灵活,所以设置的方法有很多中形式,具体的还应该根据你的平台具体的情况来设置。
mtdparts的格式如下:
mtdparts=[;
:= :[,]
:= [@offset][][ro]
:= unique id used in mapping driver/device
:= standard linux memsize OR "-" to denote all remaining space
3). 假设文件系统是jffs2类型的,且在flash中,bootargs的设置应该如下
setenv bootargs ‘mem=32M console=ttyS0,115200 noinitrd root=/dev/mtdblock2 rw rootfstype=jffs2 init=/linuxrc’
这两种方法可以用,不过很明显第二种要详细很多,请注意第二种中which netcard 是指开发板上的网卡,而不是主机上的网卡。
说完常见的几种bootargs,那么我们来讨论平常我经常使用的几种组合:
1). 假设文件系统是ramdisk,且直接就在内存中,bootargs的设置应该如下:
setenv bootargs ‘initrd=0x32000000,0xa00000 root=/dev/ram0 console=ttySAC0 mem=64M init=/linuxrc’
uboot i2c switch read 命令

uboot i2c switch read 命令U-Boot(Universal Boot Loader)是一种开源的、通用的引导加载程序,用于嵌入式操作系统,如Linux。
U-Boot提供了一组丰富的命令行接口,使得用户可以与其进行交互,执行各种任务,如启动操作系统、加载设备驱动、设置环境变量等。
在U-Boot中,如果你想要通过I2C接口读取一个开关(通常是一个I2C设备)的状态,你首先需要确保U-Boot支持I2C驱动,并且该开关设备已经被正确地配置和初始化。
一旦这些条件都满足了,你可以使用i2c命令来与I2C设备进行交互。
i2c命令通常具有多个子命令,用于执行不同的操作,如读取、写入、扫描等。
下面是一个可能的命令序列,用于通过I2C接口读取一个开关的状态:扫描I2C总线上的设备:首先,你可以使用i2c device命令来列出当前连接到I2C总线上的所有设备。
这个命令通常会告诉你每个设备的地址。
bashi2c device选择I2C设备:一旦你知道了开关设备的I2C地址,你可以使用i2c addr命令来选择一个特定的设备进行交互。
bashi2c addr <device_address>读取设备数据:一旦设备被选中,你可以使用i2c read命令来读取它的数据。
你需要指定要读取的寄存器地址和要读取的字节数。
bashi2c read <register_address> <byte_count>这些命令的具体语法和可用性可能会因U-Boot的版本和配置而异。
因此,建议查阅你正在使用的U-Boot版本的官方文档或源代码,以获取最准确的信息。
此外,需要注意的是,读取I2C设备通常需要一定的硬件知识和经验,因为你需要知道设备的具体规格和通信协议。
如果你不熟悉这些方面,可能需要参考设备的文档或联系设备的制造商以获取帮助。
uboot常用的命令

uboot常用的命令
U-Boot是一款开源的引导加载程序,它是嵌入式系统中常用的引导加载程序之一。
U-Boot提供了一系列的命令,可以用来进行系统的启动、调试、烧写等操作。
下面是U-Boot常用的命令:
1. help:显示所有可用的命令列表。
2. printenv:显示环境变量的值。
3. setenv:设置环境变量的值。
4. saveenv:保存环境变量的值。
5. bootm:启动内核。
6. tftpboot:从TFTP服务器下载文件。
7. ping:测试网络连接。
8. md:以16进制格式显示内存内容。
9. mw:以16进制格式写入内存内容。
10. cp:复制内存内容。
11. fatload:从FAT文件系统中加载文件。
12. fatls:列出FAT文件系统中的文件。
13. mmc:MMC卡操作命令。
14. usb:USB操作命令。
15. dhcp:获取IP地址。
16. run:执行脚本。
17. reset:重启系统。
以上是U-Boot常用的命令,这些命令可以满足大部分的需求。
在实
际使用中,我们可以根据具体的需求来选择合适的命令。
如果需要更
多的命令,可以通过添加自定义命令的方式来扩展U-Boot的功能。
总之,U-Boot是一款非常强大的引导加载程序,它提供了丰富的命令,
可以用来进行系统的启动、调试、烧写等操作。
熟练掌握U-Boot的命令,可以提高嵌入式系统的开发效率。
uboot命令解释与运行分析

uboot命令解释与运行分析题记: 省略200字这一回来分析一下uboot中命令行的解释, 所以我们直接从main_loop开始分析.1. 从汇编阶段进入c阶段的第一个函数是start_xxx, 如/lib_unicore/board.c中的start_unicoreboot. 前半部分调用了若干初始化函数来进行部分硬件的初始化, 并设置一下环境. 这里不是我们本回要讨论的所以一一跳过. 在start_xxx的最后调用了main_loop(), 而且还是被一个死循环死死圈住了;2. 现在我们已经进入了这个圈套那么只能往里钻了. common/main.c文件中的main_loop().上面代码主要是对自启动部分的描述, 其中命令执行部分是在run_command中进行的, 这个等在后文分析. 如果我们没有bootcmd 或者在延时中被打断, 那么代码会继续向下执行3.read_line()读取到命令行后会调用common/main.c文件中的run_command().现在是分析run_command()的时候了,不管是从环境变量还是终端获得命令,都是由run_command()来处理的.中场休息,下面要进入处理cmdbuf的循环中了, 长征马上开始以;分割. 忽略'\;'for(inquotes = 0, sep = str;*sep; sep++){if((*sep=='\'')&&(*(sep-1)!='\\'))inquotes=!inquotes;if(!inquotes &&(*sep ==';')&&( sep != str)&&(*(sep-1)!='\\'))break;}//如果上面for循环找到一条以';'结束的命令, 那么sep指向命令末尾token = str;if(*sep){str = sep + 1;*sep ='\0';}elsestr = sep;process_macros (token, finaltoken);if((argc = parse_line (finaltoken, argv))== 0){rc =-1;4.就此打断一下, 我们要分析一下find_cmd了, 不能再跳过了. find_cmd()在.u_boot_cmd段中寻找该命令的cmd_tbl_t结构, 找到后返回该结构. 该命令的结构是通过定义在include/command.h中的宏定义U_BOOT_CMD登记进.u_boot_cmd段中的.5. 刚才我们在长征的半路翻越了一座雪山, 现在继续回到while循环中if(cmdtp->cmd == do_bootd){if(flag & CMD_FLAG_BOOTD){puts("'bootd' recursion detected\n");rc =-1;continue;}else{flag |= CMD_FLAG_BOOTD;}}#endif//长征马上结束, 胜利就在眼前! 调用结构体中注册的cmd函数, 何时注册的呢? 上面不远处介绍的U_BOOT_CMD!if((cmdtp->cmd)(cmdtp, flag, argc, argv)!= 0){ rc =-1;}repeatable &= cmdtp->repeatable;if(had_ctrlc ())return-1;}。
whoami,who,w命令详解

whoami,who,w命令详解命令功能:显⽰登录⽤户的信息命令格式:常⽤选项:举例:w 显⽰已经登录的⽤户及正在进⾏的操作[root@localhost ~]# w11:22:01 up 4 days, 21:22, 3 users, load average: 0.00, 0.00, 0.00USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATroot tty1 - Thu14 4days 0.19s 0.19s -bashroot pts/0 172.31.3.32 Thu14 0.00s 0.73s 0.00s wroot pts/1 172.31.3.32 11:18 1:50 0.07s 0.02s -bashwho 显⽰已经登录的⽤户名、终端名称、登录时间及登录IP[root@localhost ~]# whoroot tty1 2015-11-12 14:00root pts/0 2015-11-12 14:03 (172.31.3.32)root pts/1 2015-11-17 11:18 (172.31.3.32)whoami 显⽰当前⽤户的⽤户名[zzd@localhost ~]$ whoamizzdwho am i 显⽰登录系统的时候的⽤户名,即使已经切换到其他⽤户也显⽰登录时的⽤户结果同who -m[zzd@localhost ~]$ whoamizzd[zzd@localhost ~]$ who am iroot pts/1 2015-11-17 11:18 (172.31.3.32)[zzd@localhost ~]$ who -mroot pts/1 2015-11-17 11:18 (172.31.3.32)显⽰当前⽤户w //显⽰当前⽤户,不显⽰登录位置19:50:14 up 9:27, 4 users, load average: 0.31, 0.26, 0.18USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATroot tty7 :0 Thu12 31:39m 10:10 0.60s gnome-sessionroot pts/0 :0.0 17:09 2:18m 15.26s 0.15s bashroot pts/1 192.168.1.17 18:51 1.00s 1.24s 0.14s -bashroot pts/2 192.168.1.17 19:48 60.00s 0.05s 0.05s -bash不显⽰登录位置w -f19:53:59 up 9:31, 4 users, load average: 0.05, 0.16, 0.15USER TTY LOGIN@ IDLE JCPU PCPU WHATroot tty7 Thu12 31:43m 10:10 0.60s gnome-sessionroot pts/0 17:09 2:21m 15.26s 0.15s bashroot pts/1 18:51 0.00s 1.04s 0.14s -bashroot pts/2 19:48 4:45 0.05s 0.05s -bash以精简模式显⽰w -s19:54:37 up 9:31, 4 users, load average: 0.24, 0.19, 0.16USER TTY FROM IDLE WHATroot tty7 :0 31:43m gnome-sessionroot pts/0 :0.0 2:22m bashroot pts/1 192.168.1.17 0.00s -bashroot pts/2 192.168.1.17 5:23 -bash不显⽰标题w -hroot tty7 :0 Thu12 31:44m 10:10 0.60s gnome-sessionroot pts/0 :0.0 17:09 2:23m 15.26s 0.15s bashroot pts/1 192.168.1.17 18:51 0.00s 1.05s 0.14s -bashroot pts/2 192.168.1.17 19:48 5:54 0.05s 0.05s -bashyexiang@ubuntu:<sboot>$ w -u yexiang14:02:04 up 9 days, 4:40, 3 users, load average: 0.99, 1.25, 0.99 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT yexiang pts/1 10.0.4.198 10:19 3.00s 0.19s 0.00s w -u yexiang。
BOOT详解

1 U-Boot简介U-Boot,全称Universal BootLoader,是遵循GPL条款的开放源码项目。
从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD,VxWorks, QNX, RTEMS, ARTOS,LynxOS嵌入式操作系统。
其目前要支持的目标操作系统是OpenBSD, NetBSD,FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR,VxWorks, LynxOS, pSOS, QNX, RTEMS,ARTOS。
这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
这两个特点正是U-Boot 项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
就目前来看,U-Boot 对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。
其它系列的处理器和操作系统基本是在2002年11月PPCBOOT改名为U-Boot后逐步扩充的。
从PPCBOOT向U-Boot 的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心WolfgangDenk[以下简称W.D]本人精湛专业水平和持着不懈的努力。
当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOTLOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。
uboot分析和笔记

uboot一、uboot是ppcboot和armboot合并而成,现在主流的bootloader为uboot和redboot二、bootm addr_kernel addr_initrd三、移植uboot时最好(一定)要找到一个自己板子的原形(即自己的板子是在这个板子上做一些修改而来的)的版本,这样就可以事半功倍。
这样要修改的地方就比较少,也比较容易了。
uboot支持很多平台,与一个具体平台相关的主要有三个地方:1、./include/configs/xxxxx.h, 主要定义了flash、sdram的起始地址等信息,一般要修改flash的起始地址、大小,有时候会有位宽等。
2、./board/xxxxx/*,这个目录下主要有两三个.c文件,主要为该平台的初始化和flash操作的函数。
有时候flash的操作需要修改,不过一般都是找一个现有的支持该flash的驱动,一般情况在uboot 别的./board/平台下就会有现成的,拷贝过了就可以了。
3、./cpu/xxxxxx/arch_xxx/xxxxxx/*, 一般是此cpu的初始等函数。
四、具体移植的时候最多涉及到的会是./include/configs/xxxx.h,如果有现成的平台(uboot现在支持绝大部分我们常用的平台),可能只需要对着原来的xxxx.h文件,修改几个我们在硬件上修改了的地方,一般会是flash的起始地址、大小;内存大小(内存的起始地址应该都是0);uboot设置信息保存的地址和长度;console 口和它的波特率;默认的设置;uboot的入口地址等(具体情况可能会有一些变化),如果不是从相同的平台移植,可能会比较麻烦,因为这时候要修改一些和此cpu相关的一些寄存器、频率和内存等硬件方面的东西了(也在这个xxxx.h中),虽然这时改动的地方也不多,但是会很痛苦,因为经常不知道要改哪里或者改为多少。
所以可能需要参考cpu的datasheet和到网上找一些资料了并且慢慢试了。
UBOOT引导Linux内核及向内核传递参数的方式

UBOOT引导Linux内核及向内核传递参数的⽅式 ⼀直以来没有想过有什么好的办法通过寄存器向内核传递参数,直到今天读UBOOT的实现⽅式。
在UBOOT中,引导内核最常⽤的⽅法是bootm命令,bootm命令可以引导“UBOOT格式”的内核。
先花点时间了解⼀下什么是“UBOOT格式”的内核吧:⽤UBOOT⾃带的mkimage命令⽣成的内核称为"UBOOT"格式的内核。
以下⾯这条命令为例: mkimage -n "Kernel 2.4.18" -A arm -O linux -T kernel -C none -a30007fc0 -e 30008000 -d 4020.bin vmlinux-2.4.18.img 其中与内核引导最密切的是-e 30008000,也就是内核的⼊⼝地址。
其它参数可以参考帮助信息。
其它UBOOT格式的内核与原来相⽐,只是进⾏(可选)了压缩,并在前⾯加了⼀个0x40⼤⼩的头。
这个头⾥放了内核的位置(0x30007fc0)和⼊⼝地址(0x30008000)和其它信息。
bootm命令执⾏时,先对头部信息等进⾏校验,然后把头信息放到⼀个结构⾥⾯。
最后根据内核类型调⽤相应的启动函数。
对于Linux⽽⾔就是do_bootm_linux,在启动函数⾥⾯,有这么⼀个操作:theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);,这是最关键的⼀个操作,将内核的⼊⼝地址0x30008000赋给了theKernel,在启动函数的最后,使⽤theKernel (0, bd->bi_arch_number, bd->bi_boot_params);启动内核。
根据传参规范,三个变量分别⽤r0,r1,r2传给内核,这样就巧妙地利⽤了函数指针进⾏了参数传递,实在是精妙!上⾯讲完了内核的引导及传参,需要引起注意的就是在使⽤mkimage命令⽣成内核时,-e后⾯的地址要⽐-a后⾯的地址偏移0x40,原因很简单,就不在细说了。
uboot相关命令及用法

uboot相关命令及⽤法进⼊uboot时,在命令⾏上敲“?” ,回车就会打印出在uboot⾥可⽤的命令:#?- alias for 'help'base - print or set address offsetboot - boot default, i.e., run 'bootcmd'bootd - boot default, i.e., run 'bootcmd'bootelf - Boot from an ELF image in memorybootm - boot application image from memorybootvx - Boot vxWorks from an ELF imagecheckcrash- check ATAGS from crash and dump to filechpart - change active partitioncmp - memory comparecp - memory copycrc32 - checksum calculationecho - echo args to consoleefuse - opt efuse dataenv - environment handling commandsexit - exit scriptext4load- load binary file from a Ext2 filesystemext4ls - list files in a directory (default /)false - do nothing, unsuccessfullyfastboot- fastbootfatinfo - print information about filesystemfatload - load binary file from a dos filesystemfatls - list files in a directory (default /)fatwrite- write file into a dos filesystemgo - start application at address 'addr'gpio - input/set/clear/toggle gpio pinshelp - print command description/usagei2c - I2C sub-systemjtag - jtag systemloop - infinite loop on address rangemd - memory displaymm - memory modify (auto-incrementing address)mmc - MMC sub systemmmcinfo - display MMC infomtdparts- define flash/nand partitionsmtest - simple RAM read/write testmw - memory write (fill)nand - NAND sub-systemnboot - boot from NAND devicenm - memory modify (constant address)nu7 - nu7 sub systempmic - pmic interfaceprintenv- print environment variablesreset - Perform RESET of the CPUrun - run commands in an environment variablesaveenv - save environment variables to persistent storagesetenv - set environment variablesshowvar - print local hushshell variablessource - run script from memorytest - minimal test like /bin/shtrue - do nothing, successfullyubi - ubi commandsubifsload- load file from an UBIFS filesystemubifsls - list files in a directoryubifsmount- mount UBIFS volumeubifsumount- unmount UBIFS volumeusb - USB sub-systemusbboot - boot from USB deviceversion - print monitor, compiler and linker version我们想要查看其中某个命令的⽤法时,在命令⾏上敲⼊“命令名?”即可,如“mmc ?”:#mmc ?mmc - MMC sub systemUsage:mmc read addr blk# cntmmc write addr blk# cntmmc erase blk# cntmmc rescanmmc part - lists available partition on current mmc devicemmc dev [dev] [part] - show or set current mmc device [partition]mmc list - lists available devicesmmc read⽤来读取mmc内容到内存,mmc write⽤来写⼊内存内容到mmc中具体⽤法,mmc read <device num> addr blk# cnt [partition]mmc write <device num> addr blk# cnt [partition]mmc listdevice num是mmc的设备号,可以通过mmc list查询addr是内存地址blk# 是mmc内的块号cnt 块数⽬使⽤范例:mmc write 2 0x90000000 0x600 0x10把内存0x90000000开始,长度为16x512⼤⼩的数据,写⼊到第2个mmc设备块偏移位置为0x600处mmc read 2 0x90000000 0x600 0x10把第⼆个mmc设备块偏移为0x600处开始,长度为16x512⼤⼩的数据,读出到内存0x90000000处从外置mmc卡load uImage⽂件:#mmc listSD/MMC: 0SD/MMC: 1#mmc dev 0mmc0 is current device#fatload mmc 0:10x82007fc0 uImage#pri#run default_bootargs只设pmic vdd:pmic vdd 1250000设置bootargs#setenv bootargs console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait gpu=384M mem=792M video=nusmartfb:${resolution}-${dispformat} 706_hw_ver=2 init=/init quiet no_console_suspend设置default_bootargs#setenv default_bootargs console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait gpu=384M mem=792M video=nusmartfb:${resolution}-${dispformat} 706_hw_ver=2 init=/init quiet no_console_suspend #ext4load mmc 1:20x82007fc0 uImage#bootm。
4.3.1U-Boot代码结构分析

4.3.1U-Boot代码结构分析4.3 Bootloader之U-BootU-Boot是在PPC-Boot的基础上进化⽽来的⼀个开放源码的嵌⼊式BootROM程序,本⼩节将使⽤1.1.4版本的代码来分析U-Boot的代码结构,以及如何将它移植到基于S3C2410X的开发板上来。
4.3.1 U-Boot代码结构分析U-Boot4-9所⽰。
board:这个⽬录存放了所有U-Boot⽀持的⽬标板的⼦⽬录,如board/smdk2410/*就和我们的开发平台fs2410相类似。
要将U-Boot移植到⾃⼰的S3C2410X⽬标板上,必须参考这个⽬录下的内容,⽐如对Flash 以及Flash宽度和⼤⼩的定制等就要修改其中的flash.c。
cpu:这个⽬录存放了U-Boot⽀持的CPU类型,因为我们的开发平台是S3C2410X,所以只关⼼cpu/arm920t,CPU相关的⽂件主要是初始化⼀个执⾏环境,包括中断的初始化;start.S是整个u-boot.bin ⽬标可执⾏代码的第⼀段代码,它们是从Flash开始运⾏的,其主要⼯作就是对整个U-Boot⽬标代码的重定位,即将U-Boot转移到内存中去运⾏。
common:这个⽬录存放了U-Boot的⼀些公共命令的实现,像那些以cmd_*.c为名字的⽂件就是对应U-Boot的每个命令的实现代码,我们通常关⼼cmd_boot.c和cmd_bootm.c(它们和内核的引导相关)。
drivers:这个⽬录中存放了各种外设接⼝的驱动程序。
fs:这个⽬录中存放了U-Boot⽀持的⽂件系统。
lib_arm:这个⽬录存放了ARM平台公共的接⼝代码。
include:这个⽬录存放头⽂件的公共⽬录,其中的include/configs/smdk2410.h定义了所有和S3C2410X 相关的资源的配置参数,我们往往只需修改这个⽂件就可以配置⽬标板的参数,如波特率、引导参数、物理内存映射等。
ubootmmc命令详解Nandflashuboot命令详解

ubootmmc命令详解Nandflashuboot命令详解
md指令
uboot下输⼊指令md,会提⽰md的⽤法,memory display,即内存显⽰。
b:8位
w:16位
l:32位(默认值)
⽰例:
上述0x10000000是要显⽰内存的那个地址,后⾯的数字是输出的个数,注意是16进制的。
直接输⼊md来显⽰,默认是以32位为单位输出。
mw指令
uboot下输⼊指令mw,会提⽰md的⽤法,memory write,即向内存中写⼊数据。
b\w\l的意思同上,address是要写⼊内存的地址,value是要写⼊的值,count是从address开始要写⼊多少个数,这些都是16进制数。
⽰例:
⽰例
在0x10000000地址内存的起始位置写⼊0x12345678,打印出内存的输出。
发现低位0x78是写在低地址0x10000000,⾼位0x12是写在⾼地址0x10000003上,也就是常说的⼩端模式(little endian),简单记忆:低低模式,即低位在低地址。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
uboot 命令解析流程简析uboot正常启动后,会调用main_loop(void)函数,进入main_loop()之后,如果在规定的时间(CONFIG_BOOTDELAY)内,没有检查到任何按键事件的发生,就会去加载OS,并启动系统,比如把linux内核压缩镜像从nand flash中读到sdram ,然后执行它。
如果在CONFIG_BOOTDELAY时间内,用户按下键盘上的任意一个按键,uboot 就会进入与用户交互的状态。
如果用户在配置文件中定义了CONFIG_SYS_HUSH_PARSER,就会通过parse_file_outer(),去接收并解析用户命令,否则进入一个for(;;)循环中,通过readline (CONFIG_SYS_PROMPT)接收用户命令,然后调用run_command(cmd,flag)去解析并执行命令。
代码如下:void main_loop(void){..............................#ifdef CONFIG_SYS_HUSH_PARSERparse_file_outer();/* This point is never reached */for (;;);#elsefor (;;){#ifdef CONFIG_BOOT_RETRY_TIMEif (rc >= 0) {/* Saw enough of a valid command to* restart the timeout.*/reset_cmd_timeout();}#endiflen = readline (CONFIG_SYS_PROMPT);printf("after readline:%d\n",len);flag = 0; /* assume no special flags for now */if (len > 0)strcpy (lastcommand, console_buffer);else if (len == 0)flag |= CMD_FLAG_REPEAT;#ifdef CONFIG_BOOT_RETRY_TIMEelse if (len == -2) {/* -2 means timed out, retry autoboot*/puts ("\nTimed out waiting for command\n");# ifdef CONFIG_RESET_TO_RETRY/* Reinit board to run initialization code again */do_reset (NULL, 0, 0, NULL);# elsereturn; /* retry autoboot */# endif}#endifif (len == -1)puts ("<INTERRUPT>\n");elserc = run_command (lastcommand, flag);.....................................}如果定义了CONFIG_SYS_HUSH_PARSER,命令接收和解析讲采用busybox 中的hush(对应hush.c)工具来实现,与uboot原始的命令解析方法相比,该工具更加智能。
这里主要讲uboot中基于hush的命令解析流程。
不过hush的实现太过复杂,鉴于自己水平太次,只是简单追踪下流程。
当在配置文件中定义了CONFIG_SYS_HUSH_PARSER,main_loop会调用parse_file_outer(),进入hush,然后里面是一大堆和hush相关的机制,暂时不做分析,最终会调用到hush中的run_pipe_real(struct pipe *pi),在该函数中经过一些列解析,最终会调用到对应的命令执行函数,代码如下:static run_pipe_real(struct pipe *pi){ ........................................rcode = (cmdtp->cmd)(cmdtp, flag,child->argc-i,&child->argv[i]);if ( !cmdtp->repeatable )flag_repeat = 0;...................................}cmdtp 是对应命令的结构指针,cmd就是该命令对应的执行函数指针。
在uboot中,对所有的命令,有一个cmd_tbl_t的结构,定义如下:struct cmd_tbl_s{char *name; /* Command Name */int maxargs; /* maximum number of arguments */int repeatable; /* autorepeat allowed? */int (*cmd)(struct cmd_tbl_s *, int, int, char *[]); /* Implementation function */char *usage; /* Usage message (short) */#ifdef CONFIG_SYS_LONGHELPchar *help; /* Help message (long) */# endif#ifdef CONFIG_AUTO_COMPLETE/* do auto completion on the arguments */int (*complete)(int argc, char *argv[], char last_char, int maxv, char*cmdv[]);#endif};typedef struct cmd_tbl_s cmd_tbl_t;#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}对于uboot支持的每一个命令,是通过U_BOOT_CMD宏定义的,他定义了该命令对应的名称name,支持的最大参数rep,重复次数,实现函数cmd,以及输入help命令时,显示的帮助信息usage。
例如,在cmd_nand中,定义nand 命令的方法如下:U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,"NAND sub-system","info - show available NAND devices\n""nand device [dev] - show or set current device\n""nand read - addr off|partition size\n""nand write - addr off|partition size\n"" read/write 'size' bytes starting at offset 'off'\n"" to/from memory address 'addr', skipping bad blocks.\n""nand erase [clean] [off size] - erase 'size' bytes from\n"" offset 'off' (entire device if not specified)\n"#if defined(ENABLE_CMD_NAND_YAFFS)"nand read[.yaffs[1]] is not provide temporarily!\n""nand write[.yaffs[1]] addr off size - write the `size' byte yaffs image starting\n" " at offset `off' from memory address `addr' (.yaffs1 for 512+16 NAND)\n"#endif"nand bad - show bad blocks\n""nand dump[.oob] off - dump page\n""nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n""nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n""nand biterr off - make a bit error at offset (UNSAFE)"#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK"\n""nand lock [tight] [status]\n"" bring nand to lock state or display locked pages\n""nand unlock [offset] [size] - unlock section"#endif);命令名称为nand,支持的最大参数个数为CONFIG_SYS_MAXARGS,命令重复次数为1,对应的实现函数为do_nand,后面的是用户输入nand -help时,将显示的帮助信息。
在执行函数cmd中,第一个参数对应该命令结构本身的指针,第二个参数对应flag标记,第三个参数对应参数数目,第四个参数是指针数组,里面存储的是对应参数的指针。
比如我们输入命令“nand read 30008000 0x80000 300000”,在run_pipe_real中,解析到该命令为nand ,有五个参数,这些参数对应的指针存储在argv数组中,nand命令对应的实现函数cmd为do_nand,在实现函数do_nand中,会从argv中取得对应的参数并解析,然后执行相应的命令。