300-mvebu-Mangle-bootloader-s-kernel-arguments.patch 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001
  2. From: Adrian Panella <[email protected]>
  3. Date: Thu, 9 Mar 2017 09:37:17 +0100
  4. Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments
  5. The command-line arguments provided by the boot loader will be
  6. appended to a new device tree property: bootloader-args.
  7. If there is a property "append-rootblock" in DT under /chosen
  8. and a root= option in bootloaders command line it will be parsed
  9. and added to DT bootargs with the form: <append-rootblock>XX.
  10. Only command line ATAG will be processed, the rest of the ATAGs
  11. sent by bootloader will be ignored.
  12. This is usefull in dual boot systems, to get the current root partition
  13. without afecting the rest of the system.
  14. Signed-off-by: Adrian Panella <[email protected]>
  15. This patch has been modified to be mvebu specific. The original patch
  16. did not pass the bootloader cmdline on if no append-rootblock stanza
  17. was found, resulting in blank cmdline and failure to boot.
  18. Signed-off-by: Michael Gray <[email protected]>
  19. ---
  20. arch/arm/Kconfig | 11 ++++
  21. arch/arm/boot/compressed/atags_to_fdt.c | 85 ++++++++++++++++++++++++-
  22. init/main.c | 16 +++++
  23. 3 files changed, 111 insertions(+), 1 deletion(-)
  24. --- a/arch/arm/Kconfig
  25. +++ b/arch/arm/Kconfig
  26. @@ -1566,6 +1566,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
  27. The command-line arguments provided by the boot loader will be
  28. appended to the the device tree bootargs property.
  29. +config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
  30. + bool "Append rootblock parsing bootloader's kernel arguments"
  31. + help
  32. + The command-line arguments provided by the boot loader will be
  33. + appended to a new device tree property: bootloader-args.
  34. + If there is a property "append-rootblock" in DT under /chosen
  35. + and a root= option in bootloaders command line it will be parsed
  36. + and added to DT bootargs with the form: <append-rootblock>XX.
  37. + Only command line ATAG will be processed, the rest of the ATAGs
  38. + sent by bootloader will be ignored.
  39. +
  40. endchoice
  41. config CMDLINE
  42. --- a/arch/arm/boot/compressed/atags_to_fdt.c
  43. +++ b/arch/arm/boot/compressed/atags_to_fdt.c
  44. @@ -6,6 +6,8 @@
  45. #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
  46. #define do_extend_cmdline 1
  47. +#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
  48. +#define do_extend_cmdline 1
  49. #else
  50. #define do_extend_cmdline 0
  51. #endif
  52. @@ -21,6 +23,7 @@ static int node_offset(void *fdt, const
  53. return offset;
  54. }
  55. +#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
  56. static int setprop(void *fdt, const char *node_path, const char *property,
  57. void *val_array, int size)
  58. {
  59. @@ -29,6 +32,7 @@ static int setprop(void *fdt, const char
  60. return offset;
  61. return fdt_setprop(fdt, offset, property, val_array, size);
  62. }
  63. +#endif
  64. static int setprop_string(void *fdt, const char *node_path,
  65. const char *property, const char *string)
  66. @@ -39,6 +43,7 @@ static int setprop_string(void *fdt, con
  67. return fdt_setprop_string(fdt, offset, property, string);
  68. }
  69. +#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
  70. static int setprop_cell(void *fdt, const char *node_path,
  71. const char *property, uint32_t val)
  72. {
  73. @@ -47,6 +52,7 @@ static int setprop_cell(void *fdt, const
  74. return offset;
  75. return fdt_setprop_cell(fdt, offset, property, val);
  76. }
  77. +#endif
  78. static const void *getprop(const void *fdt, const char *node_path,
  79. const char *property, int *len)
  80. @@ -59,6 +65,7 @@ static const void *getprop(const void *f
  81. return fdt_getprop(fdt, offset, property, len);
  82. }
  83. +#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
  84. static uint32_t get_cell_size(const void *fdt)
  85. {
  86. int len;
  87. @@ -70,6 +77,74 @@ static uint32_t get_cell_size(const void
  88. return cell_size;
  89. }
  90. +#endif
  91. +
  92. +#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
  93. +
  94. +static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
  95. +{
  96. + const char *ptr, *end;
  97. + const char *root="root=";
  98. + int i, l;
  99. + const char *rootblock;
  100. +
  101. + //ARM doesn't have __HAVE_ARCH_STRSTR, so search manually
  102. + ptr = str - 1;
  103. +
  104. + do {
  105. + //first find an 'r' at the begining or after a space
  106. + do {
  107. + ptr++;
  108. + ptr = strchr(ptr, 'r');
  109. + if (!ptr)
  110. + goto no_append;
  111. +
  112. + } while (ptr != str && *(ptr-1) != ' ');
  113. +
  114. + //then check for the rest
  115. + for(i = 1; i <= 4; i++)
  116. + if(*(ptr+i) != *(root+i)) break;
  117. +
  118. + } while (i != 5);
  119. +
  120. + end = strchr(ptr, ' ');
  121. + end = end ? (end - 1) : (strchr(ptr, 0) - 1);
  122. +
  123. + //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX )
  124. + for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
  125. + ptr = end + 1;
  126. +
  127. + /* if append-rootblock property is set use it to append to command line */
  128. + rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
  129. + if (rootblock == NULL)
  130. + goto no_append;
  131. +
  132. + if (*dest != ' ') {
  133. + *dest = ' ';
  134. + dest++;
  135. + len++;
  136. + }
  137. +
  138. + if (len + l + i <= COMMAND_LINE_SIZE) {
  139. + memcpy(dest, rootblock, l);
  140. + dest += l - 1;
  141. + memcpy(dest, ptr, i);
  142. + dest += i;
  143. + }
  144. +
  145. + return dest;
  146. +
  147. +no_append:
  148. + len = strlen(str);
  149. + if (len + 1 < COMMAND_LINE_SIZE) {
  150. + memcpy(dest, str, len);
  151. + dest += len;
  152. + }
  153. +
  154. + return dest;
  155. +}
  156. +#endif
  157. +
  158. static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
  159. {
  160. char cmdline[COMMAND_LINE_SIZE];
  161. @@ -89,18 +164,28 @@ static void merge_fdt_bootargs(void *fdt
  162. /* and append the ATAG_CMDLINE */
  163. if (fdt_cmdline) {
  164. +
  165. +#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
  166. + //save original bootloader args
  167. + //and append ubi.mtd with root partition number to current cmdline
  168. + setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
  169. + ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
  170. +
  171. +#else
  172. len = strlen(fdt_cmdline);
  173. if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
  174. *ptr++ = ' ';
  175. memcpy(ptr, fdt_cmdline, len);
  176. ptr += len;
  177. }
  178. +#endif
  179. }
  180. *ptr = '\0';
  181. setprop_string(fdt, "/chosen", "bootargs", cmdline);
  182. }
  183. +#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
  184. static void hex_str(char *out, uint32_t value)
  185. {
  186. uint32_t digit;
  187. @@ -118,6 +203,7 @@ static void hex_str(char *out, uint32_t
  188. }
  189. *out = '\0';
  190. }
  191. +#endif
  192. /*
  193. * Convert and fold provided ATAGs into the provided FDT.
  194. @@ -132,9 +218,11 @@ int atags_to_fdt(void *atag_list, void *
  195. struct tag *atag = atag_list;
  196. /* In the case of 64 bits memory size, need to reserve 2 cells for
  197. * address and size for each bank */
  198. +#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
  199. __be32 mem_reg_property[2 * 2 * NR_BANKS];
  200. - int memcount = 0;
  201. - int ret, memsize;
  202. + int memsize, memcount = 0;
  203. +#endif
  204. + int ret;
  205. /* make sure we've got an aligned pointer */
  206. if ((u32)atag_list & 0x3)
  207. @@ -169,7 +257,9 @@ int atags_to_fdt(void *atag_list, void *
  208. else
  209. setprop_string(fdt, "/chosen", "bootargs",
  210. atag->u.cmdline.cmdline);
  211. - } else if (atag->hdr.tag == ATAG_MEM) {
  212. + }
  213. +#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
  214. + else if (atag->hdr.tag == ATAG_MEM) {
  215. if (memcount >= sizeof(mem_reg_property)/4)
  216. continue;
  217. if (!atag->u.mem.size)
  218. @@ -213,6 +303,10 @@ int atags_to_fdt(void *atag_list, void *
  219. setprop(fdt, "/memory", "reg", mem_reg_property,
  220. 4 * memcount * memsize);
  221. }
  222. +#else
  223. +
  224. + }
  225. +#endif
  226. return fdt_pack(fdt);
  227. }
  228. --- a/init/main.c
  229. +++ b/init/main.c
  230. @@ -112,6 +112,10 @@
  231. #include <kunit/test.h>
  232. +#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
  233. +#include <linux/of.h>
  234. +#endif
  235. +
  236. static int kernel_init(void *);
  237. /*
  238. @@ -930,6 +934,18 @@ void start_kernel(void)
  239. boot_cpu_hotplug_init();
  240. pr_notice("Kernel command line: %s\n", saved_command_line);
  241. +
  242. +#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
  243. + //Show bootloader's original command line for reference
  244. + if(of_chosen) {
  245. + const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
  246. + if(prop)
  247. + pr_notice("Bootloader command line (ignored): %s\n", prop);
  248. + else
  249. + pr_notice("Bootloader command line not present\n");
  250. + }
  251. +#endif
  252. +
  253. /* parameters may set static keys */
  254. jump_label_init();
  255. parse_early_param();