uboot bootargs bootcmd bootm

本文详细介绍了U-Boot环境参数中的bootcmd和bootargs的作用及设置方法,并提供了多种常见场景下的实例,帮助读者理解如何配置启动命令和传递内核参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

u-boot的环境参数中有两个和内核启动相关的,它们是bootcmd和bootargs

1.u-boot中和环境参数有关的命令

       printenv:打印当前环境参数

       setenv param_name "value":设置环境参数

       saveenv:保存环境参数到FLASH

2.bootcmd:

这个参数包含了一些命令,这些命令将在u-boot进入主循环后执行

前面有说过bootcmd是自动启动时默认执行的一些命令,因此你可以在当前环境中定义各种不同配置,不同环境的参数设置,然后设置bootcmd为你经常使用的那种参数。

示例:

       bootcmd=boot_logo;nand read 10000003c0000 300000;bootm 1000000

       意思是启动u-boot后,执行boot_logo显示logo信息,然后从nand flash中读内核映像到内存,然后启动内核。

1、首先说明一下,S3C2410架构下的bootm只对sdram中的内核镜像文件进行操作(像AT91架构提供了一段从flash复制内核镜像的代码,不过针对s3c2410架构就没有这段代码,虽然可以在u-boot下添加这段代码,不过好像这个用处不大),所以请确保你的内核镜像下载到sdram中,或者在bootcmd下把flash中的内核镜像复制到sdram中。

2、-a参数后是内核的运行地址,-e参数后是入口地址。

3、
1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。
 
2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
(2)如果相同的话那就让其原封不动的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。

3.bootargs

这个参数设置要传递给内核的信息,主要用来告诉内核分区信息和根文件系统所在的分区。

bootargs是环境变量中的重中之重,甚至可以说整个环境变量都是围绕着bootargs来设置的。bootargs的种类非常非常的多,我们平常只是使用了几种而已,感兴趣的可以看看这篇文章说的很全:http://blog.chinaunix.net/u2/79570/showart_1675071.html。bootargs非常的灵活,内核和文件系统的不同搭配就会有不同的设置方法,甚至你也可以不设置bootargs,而直接将其写到内核中去(在配置内核的选项中可以进行这样的设置),正是这些原因导致了bootargs使用上的困难。


示例:

       root=/dev/mtdblock5 rootfstype=jffs2console=ttyS0,115200 mem=35M mtdparts=nand.0:3840k(u-boot),4096k(kernel),123136k(filesystem)

       其中:

       root=/dev/mtdblock5 表示根文件系统在第五分区

       rootfstype=jffs2 表示根文件系统的类型是jffs2

       console=ttyS0,115200 表示终端为ttyS0,串口波特率为115200

       mem=35M 表示内存大小为35M

       mtdparts告诉内核MTD分区情况,它在内核目录/drivers/mtd/cmdlinepart.c文件中有介绍:


下面介绍一下bootargs常用参数,bootargs的种类非常的多,而且随着kernel的发展会出现一些新的参数,使得设置会更加灵活多样。

A. root 
用来指定rootfs的位置, 常见的情况有: 
    root=/dev/ram rw   
    root=/dev/ram0 rw
  请注意上面的这两种设置情况是通用的,我做过测试甚至root=/dev/ram1 rw和root=/dev/ram2 rw也是可以的,网上有人说在某些情况下是不通用的,即必须设置成ram或者ram0,但是目前还没有遇到,还需要进一步确认,遇到不行的时候可以逐一尝试。

    root=/dev/mtdx rw
    root=/dev/mtdblockx rw
    root=/dev/mtdblock/x rw
    root=31:0x

上面的这几个在一定情况下是通用的,当然这要看你当前的系统是否支持,不过mtd是字符设备,而mtdblock是块设备,有时候你的挨个的试到底当前的系统支持上面那种情况下,不过root=/dev/mtdblockx rw比较通用。此外,如果直接指定设备名可以的话,那么使用此设备的设备号也是可以的。

    root=/dev/nfs
在文件系统为基于nfs的文件系统的时候使用。当然指定root=/dev/nfs之后,还需要指定nfsroot=serverip:nfs_dir,即指明文件系统存在那个主机的那个目录下面。

B. rootfstype 
    这个选项需要跟root一起配合使用,一般如果根文件系统是ext2的话,有没有这个选项是无所谓的,但是如果是jffs2,squashfs等文件系统的话,就需要rootfstype指明文件系统的类型,不然会无法挂载根分区.

C. console 
console=tty  使用虚拟串口终端设备 .
console=ttyS[,options] 使用特定的串口,options可以是这样的形式bbbbpnx,这里bbbb是指串口的波特率,p是奇偶位(从来没有看过使用过),n是指的bits。
console=ttySAC[,options] 同上面。

看你当前的环境,有时用ttyS,有时用ttySAC,网上有人说,这是跟内核的版本有关,2.4用ttyS,2.6用ttySAC,但实际情况是官方文档中也是使用ttyS,所以应该是跟内核版本没有关联的。可以查看Documentation/serial-console.txt找到相关描述。

D. mem
mem=xxM 指定内存的大小,不是必须的

E. ramdisk_size
ramdisk=xxxxx           不推荐   
ramdisk_size=xxxxx   推荐
上面这两个都可以告诉ramdisk 驱动,创建的ramdisk的size,默认情况下是4m(s390默认8M),你可以查看Documentation/ramdisk.txt找到相关的描述,不过ramdisk=xxxxx在新版的内核都已经没有提了,不推荐使用。

F. initrd, noinitrd
当你没有使用ramdisk启动系统的时候,你需要使用noinitrd这个参数,但是如果使用了的话,就需要指定initrd=r_addr,size, r_addr表示initrd在内存中的位置,size表示initrd的大小。

G. init
init指定的是内核启起来后,进入系统中运行的第一个脚本,一般init=/linuxrc, 或者init=/etc/preinit,preinit的内容一般是创建console,null设备节点,运行init程序,挂载一些文件系统等等操作。请注意,很多初学者以为init=/linuxrc是固定写法,其实不然,/linuxrc指的是/目录下面的linuxrc脚本,一般是一个连接罢了。

H. mtdparts
mtdparts=fc000000.nor_flash:1920k(linux),128k(fdt),20M(ramdisk),4M(jffs2),38272k(user),256k(env),384k(uboot)
要想这个参数起作用,内核中的mtd驱动必须要支持,即内核配置时需要选上Device Drivers  ---> Memory Technology Device (MTD) support  ---> Command line partition table parsing

mtdparts的格式如下:
mtdparts=[;
  := :[,]
  := [@offset][][ro]
   := unique id used in mapping driver/device
    := standard linux memsize OR "-" to denote all remaining space
    := (NAME)
因此你在使用的时候需要按照下面的格式来设置:
mtdparts=mtd-id:@(),@()
这里面有几个必须要注意的:
a.  mtd-id 必须要跟你当前平台的flash的mtd-id一致,不然整个mtdparts会失效
b.  size在设置的时候可以为实际的size(xxM,xxk,xx),也可以为'-'这表示剩余的所有空间。
举例:
假设flash 的mtd-id是sa1100,那么你可以使用下面的方式来设置:
mtdparts=sa1100:-     →  只有一个分区
mtdparts=sa1100:256k(ARMboot)ro,-(root)  →  有两个分区
可以查看drivers/mtd/cmdlinepart.c中的注释找到相关描述。

I. ip
指定系统启动之后网卡的ip地址,如果你使用基于nfs的文件系统,那么必须要有这个参数,其他的情况下就看你自己的喜好了。设置ip有两种方法:
ip = ip addr
ip=ip addr:server ip addr:gateway:netmask::which netcard:off
这两种方法可以用,不过很明显第二种要详细很多,请注意第二种中which netcard 是指开发板上的网卡,而不是主机上的网卡。

说完常见的几种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’

4). 假设文件系统是基于nfs的,bootargs的设置应该如下
setenv bootargs ‘noinitrd mem=64M console=ttySAC0 root=/dev/nfs nfsroot=192.168.0.3:/nfs ip=192.168.0.5:192.168.0.3:192.168.0.3:255.255.255.0::eth0:off’
或者
setenv bootargs ‘noinitrd mem=64M console=ttySAC0 root=/dev/nfs nfsroot=192.168.0.3:/nfs ip=192.168.0.5’


上面就是我们经常使用的几种bootargs的组合,老实说,bootargs非常非常的灵活,所以设置的方法有很多中形式,具体的还应该根据你的平台具体的情况来设置。

<think>好的,我需要解决用户的问题:在MIPS架构下如何将U-Boot的bootargs参数复制到boot_command_line中。首先,我得回顾一下之前用户提到的内容,以及相关的引用资料。用户之前的问题是关于MIPS如何附加设备树和使用bootargs,现在转向了U-Boot的bootargs如何传递到内核的boot_command_line。根据引用[2],U-Boot的main_loop函数会获取bootcmdbootargs环境变量,并执行启动命令。用户现在想知道这个过程在MIPS架构下的具体实现机制。首先,我需要回忆Linux内核启动时如何处理bootargs。通常,U-Boot会将bootargs传递给内核,内核在启动过程中解析这些参数。在MIPS架构中,这个过程可能涉及到特定的代码路径,比如prom_init中的处理。根据之前的回答,MIPS内核可以通过附加设备树的方式获取参数,但这里用户关注的是传统方式(非设备树)下bootargs的传递。需要查阅MIPS内核启动代码,特别是处理命令行参数的部分。例如,在prom_init函数中,可能会从U-Boot传递的参数中获取命令行,并复制到boot_command_line变量中。另外,引用[3]提到用户在使用U-Boot时遇到复位的问题,可能与某些初始化过程有关,比如timer_init。这可能影响U-Boot正确传递参数到内核,但当前问题主要关注参数的复制机制,而不是错误处理。 我需要确认MIPS架构下内核如何接收U-Boot传递的bootargs。可能的路径是:U-Boot将bootargs放在特定的寄存器或内存地址中,内核在启动时从该地址读取并处理。例如,在MIPS的setup_arch函数中,可能会有代码解析这些参数。接下来,需要找到内核中处理bootargs的具体函数。在ARM架构中,通常会通过tag列表传递参数,而MIPS可能有类似机制。比如,通过atag或fw_arg0、fw_arg1等参数传递命令行字符串的地址。 例如,在MIPS的prom_init代码中,可能存在如下逻辑: 1. U-Boot将bootargs字符串的地址通过某个寄存器(如$a0)传递给内核。 2.内核在启动时(通常是prom_init阶段)读取该地址处的字符串。3.将字符串复制到boot_command_line变量中。具体代码可能类似于: char*bootargs =(char*)fw_arg0; strlcpy(boot_command_line, bootargs,COMMAND_LINE_SIZE);这需要验证内核源代码中的实际实现。例如,在arch/mips/kernel/setup.c或prom.c中查找相关代码。 同时,用户可能需要了解如何确保U-Boot正确设置bootargs,以及内核如何正确接收。例如,在U-Boot中使用setenv bootargs ...,并确保启动命令正确传递参数。 还需要考虑设备树的情况,如果使用设备树,bootargs可能存储在chosen节点中,内核会从那里读取。但用户的问题明确提到U-Boot的bootargs复制到boot_command_line,可能涉及非设备树的情况。总结步骤: 1. U-Boot设置bootargs环境变量。2.U-Boot将bootargs字符串地址通过启动参数传递给内核。3.内核在启动初期(如prom_init)读取该地址,并复制到boot_command_line。4.后续内核初始化流程使用boot_command_line进行参数解析。 需要引用具体的代码部分来支持这一过程,并指出关键函数和变量。同时,可能需要说明在MIPS架构下参数传递的具体寄存器或内存约定。最后,生成相关问题,帮助用户进一步理解参数传递机制和可能的问题排查方法。</think>### MIPS架构下U-Boot bootargs复制到boot_command_line的实现机制 --- #### 一、参数传递架构约定 在MIPS架构中,U-Boot与Linux内核通过**约定寄存器**传递启动参数: - `$a1`寄存器:存储设备树地址(DTB模式) - **`$a0`寄存器**:存储命令行参数地址(非DTB模式)[^1][^2] 当内核启动时,通过`fw_arg0`变量获取寄存器`$a0`的值,该值指向U-Boot设置的`bootargs`字符串内存地址[^2]。 --- #### 二、内核参数接收代码分析 内核在初始化阶段通过`prom_init()`函数处理命令行参数: ```c // arch/mips/kernel/setup.c void __init prom_init(void) { char *cmdline = (char *)fw_arg0; // 从$a0获取参数地址 strlcpy(boot_command_line, cmdline, COMMAND_LINE_SIZE); /* 其他架构初始化操作 */ } ``` 此处`fw_arg0`对应U-Boot传递的`bootargs`物理地址,内核将其内容复制到全局变量`boot_command_line`[^1][^2]。 --- #### 三、关键数据流验证 | 阶段 | 操作 | 验证方法 | |------|------|----------| | **U-Boot设置** | `setenv bootargs console=ttyS0,115200 root=/dev/nfs` | 使用`printenv`命令确认参数正确性 | | **寄存器传递** | U-Boot启动内核时设置`$a0`寄存器 | 通过反汇编查看`bootm`命令的寄存器操作 | | **内核接收** | `prom_init()`读取`fw_arg0` | 添加`pr_info("cmdline: %s\n", boot_command_line);`调试输出 | --- #### 四、调试技巧 ##### 1. 内核启动日志检查 在内核配置中启用启动参数调试: ```kconfig CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE_OVERRIDE=y CONFIG_DEBUG_LL=y ``` 启动时观察日志输出: ```bash [ 0.000000] Kernel command line: console=ttyS0,115200 root=/dev/nfs ``` ##### 2. U-Boot内存映射验证 在U-Boot中使用`md`命令查看参数存储地址: ```bash => md 0x80100000 10 # 假设$a0=0x80100000 ``` 应显示完整的`bootargs`字符串内容[^3]。 --- #### 五、特殊场景处理 当同时存在**附加设备树(DTB)**时,参数传递优先级为: 1. 设备树`chosen`节点中的`bootargs` 2. U-Boot通过`$a0`传递的`bootargs` 3. 内核编译时默认配置的`CONFIG_CMDLINE` 内核会通过`of_scan_flat_dt()`优先解析设备树中的参数[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值