diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 19 | ||||
-rw-r--r-- | arch/arm/boot/compressed/atags_to_fdt.c | 62 |
2 files changed, 79 insertions, 2 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b649c5904a4f..8c9d264f2108 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1960,6 +1960,25 @@ config ARM_ATAG_DTB_COMPAT | |||
1960 | bootloaders, this option allows zImage to extract the information | 1960 | bootloaders, this option allows zImage to extract the information |
1961 | from the ATAG list and store it at run time into the appended DTB. | 1961 | from the ATAG list and store it at run time into the appended DTB. |
1962 | 1962 | ||
1963 | choice | ||
1964 | prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT | ||
1965 | default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER | ||
1966 | |||
1967 | config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER | ||
1968 | bool "Use bootloader kernel arguments if available" | ||
1969 | help | ||
1970 | Uses the command-line options passed by the boot loader instead of | ||
1971 | the device tree bootargs property. If the boot loader doesn't provide | ||
1972 | any, the device tree bootargs property will be used. | ||
1973 | |||
1974 | config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND | ||
1975 | bool "Extend with bootloader kernel arguments" | ||
1976 | help | ||
1977 | The command-line arguments provided by the boot loader will be | ||
1978 | appended to the the device tree bootargs property. | ||
1979 | |||
1980 | endchoice | ||
1981 | |||
1963 | config CMDLINE | 1982 | config CMDLINE |
1964 | string "Default kernel command string" | 1983 | string "Default kernel command string" |
1965 | default "" | 1984 | default "" |
diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c index 797f04bedb47..aabc02a68482 100644 --- a/arch/arm/boot/compressed/atags_to_fdt.c +++ b/arch/arm/boot/compressed/atags_to_fdt.c | |||
@@ -1,6 +1,12 @@ | |||
1 | #include <asm/setup.h> | 1 | #include <asm/setup.h> |
2 | #include <libfdt.h> | 2 | #include <libfdt.h> |
3 | 3 | ||
4 | #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND) | ||
5 | #define do_extend_cmdline 1 | ||
6 | #else | ||
7 | #define do_extend_cmdline 0 | ||
8 | #endif | ||
9 | |||
4 | static int node_offset(void *fdt, const char *node_path) | 10 | static int node_offset(void *fdt, const char *node_path) |
5 | { | 11 | { |
6 | int offset = fdt_path_offset(fdt, node_path); | 12 | int offset = fdt_path_offset(fdt, node_path); |
@@ -36,6 +42,48 @@ static int setprop_cell(void *fdt, const char *node_path, | |||
36 | return fdt_setprop_cell(fdt, offset, property, val); | 42 | return fdt_setprop_cell(fdt, offset, property, val); |
37 | } | 43 | } |
38 | 44 | ||
45 | static const void *getprop(const void *fdt, const char *node_path, | ||
46 | const char *property, int *len) | ||
47 | { | ||
48 | int offset = fdt_path_offset(fdt, node_path); | ||
49 | |||
50 | if (offset == -FDT_ERR_NOTFOUND) | ||
51 | return NULL; | ||
52 | |||
53 | return fdt_getprop(fdt, offset, property, len); | ||
54 | } | ||
55 | |||
56 | static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) | ||
57 | { | ||
58 | char cmdline[COMMAND_LINE_SIZE]; | ||
59 | const char *fdt_bootargs; | ||
60 | char *ptr = cmdline; | ||
61 | int len = 0; | ||
62 | |||
63 | /* copy the fdt command line into the buffer */ | ||
64 | fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len); | ||
65 | if (fdt_bootargs) | ||
66 | if (len < COMMAND_LINE_SIZE) { | ||
67 | memcpy(ptr, fdt_bootargs, len); | ||
68 | /* len is the length of the string | ||
69 | * including the NULL terminator */ | ||
70 | ptr += len - 1; | ||
71 | } | ||
72 | |||
73 | /* and append the ATAG_CMDLINE */ | ||
74 | if (fdt_cmdline) { | ||
75 | len = strlen(fdt_cmdline); | ||
76 | if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) { | ||
77 | *ptr++ = ' '; | ||
78 | memcpy(ptr, fdt_cmdline, len); | ||
79 | ptr += len; | ||
80 | } | ||
81 | } | ||
82 | *ptr = '\0'; | ||
83 | |||
84 | setprop_string(fdt, "/chosen", "bootargs", cmdline); | ||
85 | } | ||
86 | |||
39 | /* | 87 | /* |
40 | * Convert and fold provided ATAGs into the provided FDT. | 88 | * Convert and fold provided ATAGs into the provided FDT. |
41 | * | 89 | * |
@@ -72,8 +120,18 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) | |||
72 | 120 | ||
73 | for_each_tag(atag, atag_list) { | 121 | for_each_tag(atag, atag_list) { |
74 | if (atag->hdr.tag == ATAG_CMDLINE) { | 122 | if (atag->hdr.tag == ATAG_CMDLINE) { |
75 | setprop_string(fdt, "/chosen", "bootargs", | 123 | /* Append the ATAGS command line to the device tree |
76 | atag->u.cmdline.cmdline); | 124 | * command line. |
125 | * NB: This means that if the same parameter is set in | ||
126 | * the device tree and in the tags, the one from the | ||
127 | * tags will be chosen. | ||
128 | */ | ||
129 | if (do_extend_cmdline) | ||
130 | merge_fdt_bootargs(fdt, | ||
131 | atag->u.cmdline.cmdline); | ||
132 | else | ||
133 | setprop_string(fdt, "/chosen", "bootargs", | ||
134 | atag->u.cmdline.cmdline); | ||
77 | } else if (atag->hdr.tag == ATAG_MEM) { | 135 | } else if (atag->hdr.tag == ATAG_MEM) { |
78 | if (memcount >= sizeof(mem_reg_property)/4) | 136 | if (memcount >= sizeof(mem_reg_property)/4) |
79 | continue; | 137 | continue; |