貌似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);
}
的回调函数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: |
再次检查了一遍,这些开关确实没有打开,那就说明,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