WRTNode(MT7620) 通过USB启动OpenWRT过程记录(中)

29 篇文章 2 订阅
16 篇文章 0 订阅

貌似kernel忽略了bootargs

代码位于build_dir…arch/mips/ralink中的prom.c

static __init void prom_init_cmdline(int argc, char **argv)
{
    int i;
    // manfeel , mod to pr_info from pr_debug
    pr_info("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n",
           (unsigned int)fw_arg0, (unsigned int)fw_arg1,
           (unsigned int)fw_arg2, (unsigned int)fw_arg3);
 
    argc = fw_arg0;
    argv = (char **) KSEG1ADDR(fw_arg1);
 
    if (!argv) {
        // manfeel , mod to pr_info from pr_debug
        pr_info("argv=%p is invalid, skipping\n",
               argv);
        return;
    }
 
    for (i = 0; i < argc; i++) {
        char *p = (char *) KSEG1ADDR(argv[i]);
 
        if (CPHYSADDR(p) && *p) {
            // manfeel , mod to pr_info from pr_debug
            pr_info("argv[%d]: %s\n", i, p);
            strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
            strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
        }
    }
    pr_info("arcs_cmdline : %s\n",arcs_cmdline);
}

在prom.c中,uboot中的bootargs被读入到arcs_cmdline中。

然而,setup.c中却没有读到这个arcs_cmdline!Why?

在涉及到arcs_cmdline的地方,进行诊断输出,启动时刻,在控制台发现了如下信息:

SoC is Ralink MT7620N ver:2 eco:3
prom: fw_arg0=00000003 fw_arg1=83f02fb0 fw_arg2=83f033d0 fw_arg3=00000000
argv[1]: root=/dev/root
argv[2]: debug
0 arch/mips/ralink/prom.c,arcs_cmdline =  root=/dev/root debug
bootconsole [early0] enabled
CPU revision is: 00019650 (MIPS 24KEc)
1 arch/mips/kernel/prom.c,arcs_cmdline =  root=/dev/root debug
2 arch/mips/kernel/prom.c,arcs_cmdline = console=ttyS0,57600
MIPS: machine is WRTNode

可以确定,arcs_cmdline在ralink/prom.c中被正确置入,却在kernel/prom.c中被修改成系统默认的!!!

我们跟踪进入,一探究竟。

void __init early_init_devtree(void *params)
{
    /* Setup flat device-tree pointer */
    initial_boot_params = params;
 
    /* Retrieve various informations from the /chosen node of the
     * device-tree, including the platform type, initrd location and
     * size, and more ...
     */
    // manfeel debug output 
    //pr_info("1 %s,arcs_cmdline = %s\n",__FILE__,arcs_cmdline);
    of_scan_flat_dt(early_init_dt_scan_chosen, arcs_cmdline);
    //pr_info("2 %s,arcs_cmdline = %s\n",__FILE__,arcs_cmdline);
 
 
    /* Scan memory nodes */
    of_scan_flat_dt(early_init_dt_scan_root, NULL);
    of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
 
    /* try to load the mips machine name */
    of_scan_flat_dt(early_init_dt_scan_model, NULL);
}
仔细研究以后,发现关键的代码,是在调用of_scan_flat_dt(early_init_dt_scan_chosen, arcs_cmdline);

的回调函数early_init_dt_scan_chosen中,该函数位于drivers/of/fdt.c中

int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
                     int depth, void *data)
{
    unsigned long l;
    char *p;
 
    pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 
    if (depth != 1 || !data ||
        (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
        return 0;
 
    early_init_dt_check_for_initrd(node);
 
    /* Retrieve command line */
    p = of_get_flat_dt_prop(node, "bootargs", &l);
    if (p != NULL && l > 0)
        strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
    p = of_get_flat_dt_prop(node, "bootargs-append", &l);
    if (p != NULL && l > 0)
        strlcat(data, p, min(strlen(data) + (int)l, COMMAND_LINE_SIZE));
 
    /*
     * CONFIG_CMDLINE is meant to be a default in case nothing else
     * managed to set the command line, unless CONFIG_CMDLINE_FORCE
     * is set in which case we override whatever was found earlier.
     */
#ifdef CONFIG_CMDLINE
#ifndef CONFIG_CMDLINE_FORCE
    if (!((char *)data)[0])
#endif
        strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#endif /* CONFIG_CMDLINE */
 
    pr_debug("Command line is: %s\n", (char*)data);
 
    /* break now */
    return 1;
}

里面的*data就是arcs_cmdline!

CONFIG_CMDLINE和CONFIG_CMDLINE_FORCE来自kernel_menuconfig中的:

Kernel hacking ---> [ ] Built-in kernel command line

里面有段说明:

CONFIG_CMDLINE_BOOL:
For most systems, it is firmware or second stage bootloader that
by default specifies the kernel command line options. However,
it might be necessary or advantageous to either override the
default kernel command line or add a few extra options to it.
For such cases, this option allows you to hardcode your own
command line options directly into the kernel. For that, you
should choose 'Y' here, and fill in the extra boot arguments
in CONFIG_CMDLINE.
The built-in options will be concatenated to the default command
line if CMDLINE_OVERRIDE is set to 'N'. Otherwise, the default
command line will be ignored and replaced by the built-in string.
Most MIPS systems will normally expect 'N' here and rely upon
the command line from the firmware or the second-stage bootloader.
Symbol: CMDLINE_BOOL [=n]
Type : boolean
Prompt: Built-in kernel command line
Location:
-> Kernel hacking
Defined at arch/mips/Kconfig.debug:23

再次检查了一遍,这些开关确实没有打开,那就说明,of_get_flat_dt_prop函数有问题!

/* Retrieve command line */
p = of_get_flat_dt_prop(node, "bootargs", &l);
if (p != NULL && l > 0)
    strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
p = of_get_flat_dt_prop(node, "bootargs-append", &l);
if (p != NULL && l > 0)
    strlcat(data, p, min(strlen(data) + (int)l, COMMAND_LINE_SIZE));

bootargs在prom.c已经被成功读出,为什么在这里还要继续折腾呢-_-||| 

猛然意识到,这段代码是在DTS里面读取属性值!

找到target/linux/ramips/dts里面的mt7620n.dtsi,发现里面有这样的定义:

	chosen {
		bootargs = "console=ttyS0,57600";
	};
果断删掉这一节的定义!

在uboot中设置bootargs为root=/dev/sda2 rootfstype=ext4 console=ttyS0,57600n8

注意:console=ttyS0,57600n8很关键,不然到启动后期,控制台就不可见了。

重新编译以后,kernel终于能够处理bootargs了!但是仍然是panic!

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

automount rootfs已经关闭:

<*> Memory Technology Device (MTD) support --->

OpenWrt specific MTD options --->

[*] Automatically set 'rootfs' partition to be root filesystem

在OpenWRT的menuconfig中,已经加入了usb storage的支持。

问题在哪里呢?会不会是在设置rootfs的时刻,storage驱动还未加载呢?

有些kernel需要参考这篇文章:https://github.com/8devices/u-boot/issues/3

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值