提交 d0f34a11 编写于 作者: G Genoud Richard 提交者: Russell King

ARM: 7437/1: zImage: Allow DTB command line concatenation with ATAG_CMDLINE

This patch allows the ATAG_CMDLINE provided by the bootloader to be
concatenated to the bootargs property of the device tree.

This is useful to merge static values defined in the device tree
with the boot loader's (possibly) more dynamic values, such as
startup reasons and more.

The bootloader should use the device tree to pass those values to
the kernel, but that's not always simple (old bootloader or very
small one).

The behaviour is the same as the one introduced by Victor Boivie in
4394c124 by extending the CONFIG_CMDLINE.
Signed-off-by: NRichard Genoud <richard.genoud@gmail.com>
Tested-by: NGregory CLEMENT <gregory.clement@free-electrons.com>
Acked-by: NNicolas Pitre <nico@linaro.org>
Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
上级 9ad86ddd
...@@ -1960,6 +1960,25 @@ config ARM_ATAG_DTB_COMPAT ...@@ -1960,6 +1960,25 @@ config ARM_ATAG_DTB_COMPAT
bootloaders, this option allows zImage to extract the information bootloaders, this option allows zImage to extract the information
from the ATAG list and store it at run time into the appended DTB. from the ATAG list and store it at run time into the appended DTB.
choice
prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT
default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
bool "Use bootloader kernel arguments if available"
help
Uses the command-line options passed by the boot loader instead of
the device tree bootargs property. If the boot loader doesn't provide
any, the device tree bootargs property will be used.
config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND
bool "Extend with bootloader kernel arguments"
help
The command-line arguments provided by the boot loader will be
appended to the the device tree bootargs property.
endchoice
config CMDLINE config CMDLINE
string "Default kernel command string" string "Default kernel command string"
default "" default ""
......
#include <asm/setup.h> #include <asm/setup.h>
#include <libfdt.h> #include <libfdt.h>
#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
#define do_extend_cmdline 1
#else
#define do_extend_cmdline 0
#endif
static int node_offset(void *fdt, const char *node_path) static int node_offset(void *fdt, const char *node_path)
{ {
int offset = fdt_path_offset(fdt, node_path); int offset = fdt_path_offset(fdt, node_path);
...@@ -36,6 +42,48 @@ static int setprop_cell(void *fdt, const char *node_path, ...@@ -36,6 +42,48 @@ static int setprop_cell(void *fdt, const char *node_path,
return fdt_setprop_cell(fdt, offset, property, val); return fdt_setprop_cell(fdt, offset, property, val);
} }
static const void *getprop(const void *fdt, const char *node_path,
const char *property, int *len)
{
int offset = fdt_path_offset(fdt, node_path);
if (offset == -FDT_ERR_NOTFOUND)
return NULL;
return fdt_getprop(fdt, offset, property, len);
}
static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
{
char cmdline[COMMAND_LINE_SIZE];
const char *fdt_bootargs;
char *ptr = cmdline;
int len = 0;
/* copy the fdt command line into the buffer */
fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len);
if (fdt_bootargs)
if (len < COMMAND_LINE_SIZE) {
memcpy(ptr, fdt_bootargs, len);
/* len is the length of the string
* including the NULL terminator */
ptr += len - 1;
}
/* and append the ATAG_CMDLINE */
if (fdt_cmdline) {
len = strlen(fdt_cmdline);
if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
*ptr++ = ' ';
memcpy(ptr, fdt_cmdline, len);
ptr += len;
}
}
*ptr = '\0';
setprop_string(fdt, "/chosen", "bootargs", cmdline);
}
/* /*
* Convert and fold provided ATAGs into the provided FDT. * Convert and fold provided ATAGs into the provided FDT.
* *
...@@ -72,8 +120,18 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) ...@@ -72,8 +120,18 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space)
for_each_tag(atag, atag_list) { for_each_tag(atag, atag_list) {
if (atag->hdr.tag == ATAG_CMDLINE) { if (atag->hdr.tag == ATAG_CMDLINE) {
setprop_string(fdt, "/chosen", "bootargs", /* Append the ATAGS command line to the device tree
atag->u.cmdline.cmdline); * command line.
* NB: This means that if the same parameter is set in
* the device tree and in the tags, the one from the
* tags will be chosen.
*/
if (do_extend_cmdline)
merge_fdt_bootargs(fdt,
atag->u.cmdline.cmdline);
else
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
} else if (atag->hdr.tag == ATAG_MEM) { } else if (atag->hdr.tag == ATAG_MEM) {
if (memcount >= sizeof(mem_reg_property)/4) if (memcount >= sizeof(mem_reg_property)/4)
continue; continue;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册