(1)基础命令
dnw:在进入系统之前进入指令行,输入该指令可下载烧录文件。
re:重新启动嵌入式系统。
printenv:打印当前系统环境变量。
setenv:设置环境变量,格式:setenv name value ...,表示将name 变量设置成value 值;如果没有这个参数,表示删除该变量。
saveenv:保存环境变量到NAND中。
sleep:延迟执行,格式:sleep N,可以延迟N秒钟执行。
run:执行环境变量中的命令,格式:run var,可以跟几个环境变量名。
crc32:计算校验值,格式:crc32 address count [addr],第一个参数是需校验的起始地址,第二个参数是校验的数据字节数,第三个参 数是保存校验值的地址。
cp:在内存中复制数据块,格式:cp source target count,第一个参数是源地址,第二个参数是目的地址,第三个参数是复制数目。
cmp:比较内存中的数据块,格式:cmp addr1 addr2 count,第一个参数是内存地址一,第二个参数是内存地址二,第三个是比较长度(单位是字节数除以4,以WORDS为单位)。
bootm:可以引导启动存储在内存中的程序映像。格式:bootm addr1 addr2,第一个参数是程序映像的地址,第二个参数一般是RAMDISK地址。
nand scrub:暴力擦除指令,擦除整个NAND,会擦除bad block标记。
nand erase:擦除NAND,格式:nand erase addr1 count,第一个参数是OFFSET,第二个参数是擦除字节数。其中OFFSET是相对于Download地址。
nand write:下载的内存数据写入NAND,格式:nand write addr offset count,第一个参数是写入基地址,第二个参数是偏移地址,第三个参数是写入字节数。
nand read:讲NAND数据读取到内存,格式:nand read addr offset count,第一个参数是读取的NAND地址,第二个参数是内存位置偏移,第三个参数是读取字节数。
nand bad:测试NAND FLASH坏块的命令。如:nand bad,即可显示坏的区块地址。
(2)测试
通常我们会回写数据来测试写入跟读取的数据是否一致,如:
假设Download Address: 0xc0000000,Download Filesize:0x1df48c
nand erase 600000 300000 //擦除c0600000为开始的300000个字节
nand write c0000000 600000 300000 //往刚擦除的空间写入内存起始地址的数据共300000个长度
nand read c0600000 600000 300000 //读取刚写入的NAND地址共300000个长度到偏移600000的内存中
cmp c0600000 c0000000 300000 //比较两段内存的数据是否相同
此通常会用在DDR调试上,比如128MDDR的MEMORY MAP基地址是0X50000000,空间从0X50000000-0X58000000,如果要改软件支持到256M,假设DOWNLOAD地址是0XC0000000,通过内存拷贝和比较命令来对比0XC0000000和0X59000000的内容是否一致。
(3)引用别人之前的解决的一个问题:
当把u-boot下载进去,再把内核下进去后发现,内核跑不起来。反反复复尝试,还是没有进展。在一篇文章中看到了u-boot源代码的配制文件config.mk,打开这个文件,看到内核的启动地址是0x50008000与用户手册上的0xc0008000不一样。就按照这个搞了一下,果然就可以启动内核了。但还是不能烧到flash里去,后来用nand bad命令发现:存放内核的nand flash启始地址是个坏块。所以将内核存在了扩展区才搞成功。
==========================================================================================================================
编好了u-boot,但是如何来使用却不是那么简单的,u-boot的环境变量经常设置错误而导致内核启动失败。它可以由你自己定义的,但是其中有一些也是大家经常使用约定俗成的,更改这些名字会出现错误,下面的表中我们列出了一些常用的环境变量:
bootdelay 执行自动启动的等候秒数
baudrate 串口控制台的波特率
netmask 以太网接口的掩码
ethaddr 以太网卡的网卡物理地址
bootargs 传递给内核的启动参数
bootcmd 自动启动时执行的命令
serverip 服务器端的ip地址
ipaddr 本地ip 地址
stdin 标准输入设备
stdout 标准输出设备
stderr 标准出错设备
上面只是一些最基本的环境变量,板子里原本是没有环境变量的,u-boot的缺省情况下会有一些基本的环境变量,在你执行了saveenv之后,环境变量会第一次保存到flash中,之后你对环境变量的修改、保存都是基于保存在flash中的环境变量的操作。U-boot的环境变量值得注意的有两个: bootcmd 和bootargs。
(1)bootcmd,是自动启动时默认执行的一些命令,因此你可以在当前环境中定义各种不同配置,不同环境的参数设置,然后设置bootcmd为你经常使用的那种参数。
(2)bootargs,是环境变量中的重中之重,可以说整个环境变量都是围绕着bootargs来设置的。bootargs的种类非常非常的多,我们平常只是使用了几种而已,bootargs非常的灵活,内核和文件系统的不同搭配就会有不同的设置方法,甚至你也可以不设置bootargs而直接将其写到内核中去(在配置内核的选项中可以进行这样的设置)。
A,root:用来指定rootfs的位置,常见的情况有:root=/dev/mtdx rw 或 root=/dev/mtdblockx rw 或 root=/dev/mtdblock/x rw等。
B,rootfstype:这个选项需要跟root一起配合使用,一般如果根文件系统是ext2的话,有没有这个选项是无所谓的,但是如果是jffs2等文件系统的话,就需要rootfstype指明文件系统的类型,不然会无法挂载根分区。
C,console:console=tty<n> 使用虚拟串口终端设备 <n>。比如console=ttySAC0,115200
D,mem:mem=xxM 指定内存的大小,不是必须的。
E,ramdisk_size:ramdisk_size=xxxxx,告诉ramdisk 驱动,创建的ramdisk的size。
F, initrd, noinitrd:当你没有使用ramdisk启动系统的时候,你需要使用noinitrd这个参数,但是如果使用了的话,就需要指定initrd=r_addr,size, r_addr表示initrd在
内存中的位置,size表示initrd的大小。
G. init:init指定的是内核启起来后,进入系统中运行的第一个脚本,一般init=/linuxrc,运行init程序,挂载一些文件系统等等操作。请注意,很多初学者以为init=/linuxrc是固定写法,其实不然,/linuxrc指的是/目录下面的linuxrc脚本,一般是一个连接罢了。
说完常见的几种bootargs,那么我们来讨论平常我经常使用的几种组合:
1),假设文件系统是ramdisk,且直接就在内存中,bootargs的设置应该如下:
setenv bootargs ‘initrd=0x32000000,0xa00000 root=/dev/ram0 console=ttySAC0 mem=64M init=/linuxrc’
2),假设文件系统是ramdisk,且在flash中,bootargs的设置应该如下:
setenv bootargs ‘mem=32M console=ttyS0,115200 root=/dev/ram rw init=/linuxrc’
注意这种情况下你应该要在bootm命令中指定ramdisk在flash中的地址,如bootm kernel_addr ramdisk_addr (fdt_addr)
3),假设文件系统是jffs2类型的,且在flash中,bootargs的设置应该如下
setenv bootargs ‘mem=32M console=ttyS0,115200 noinitrd root=/dev/mtdblock2 rw rootfstype=jffs2 init=/linuxrc’
补充一下bootargs的解析过程:在/arch/arm/kernel/setup.c,查找函数parse_tag_cmdline(),bootloader的命令行就是通过这个函数传递给kernel的。可以直接屏蔽掉这个函数中的命令行传递,在kernel的.config下直接写入你想要的命令行参数。
======================================================================================================================
Linux开机常见错误:
(1)下载内核到flash中,运行到如下即停止没有下文: Uncompressing Linux……………………done,booting the kernel ,卡在这里不动了。
原因分析:可能是内核的启动参数传递时没有填写正确,也可能是在linux内核中没对flash分区。
解决办法:如果是命令参数问题,注释掉arch/arm/kernel/setup.c文件中的parse_tag_cmdline()函数中的strlcpy()函数,这样就可以使用默认的CONFIG_CMDLINE了,在.config文件中它被定义为"root=/dev/mtdblock2 ro init=/linuxrc console=ttySAC0,115200"(视具体情况而定),或者在内核配置文件的Boot options中填入也可。如果是分区的问题,就核对分区。
(2)出现如下错误:
VFS:Cannot open root device "mtdblock/2" or unknown-block(0,0)
Please append a correct "root=" boot option.
Kernel panic not syncing,VFS Unable to mount root fs on unknown-block(0,0)
原因分析:出现这种情况一般有两种情况:没有文件系统或boot options参数不正确,如我的系统文件系统为cramfs格式,存放文件系统的分区为第三个分区,启动参数为:
"noinitrd root=/dev/mtdblock2 ro init=/linuxrc console=ttySAC0,115200 rootfstype=cramfs mem=64M"
曾经碰到过一个类似的现象,就是因为新的bootargs没有覆盖掉旧的bootargs,导致每次开机后没有挂接cramfs就直接去挂载后面的ubi sys,提示cramfs也失败,Ubi也失败。重设环境变量并保存后OK。
(3) 系统启动后出现如下错误: Kernel panic -not syncing:VFS:Unable to mount root fs on unknown-block(31,2) 或者类似的错误。
原因分析:这种情况一般是NAND flash分区未能分正确,或者所在的分区上没有文件系统。