Skip to contentSkip to conversation

Improve arm64 support

RFC PATCH Superseded Tom Rini 2 participants 9 messages May 5, 2014 – May 14, 2014

Subsystems (2)

v0 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Tom Rini

author
#0 lore raw

cover Improve arm64 support

After talking with some folks at ELC and getting a feel for some things, here is a series to start addressing some issues with the ARM64 port.

The following RFC series corrects our passing of args to the Linux kernel and cleans up the vexpress_aemv8a config a bit (and corrects some values too).

This also adds support for Image booting. This isn't 100% ready to merge in that it exposes an issue which will be addressed in the kernel soon. The Image format doesn't say how big it is, so for now I hack in a value of 16MB. I've been told this will change in the future (and one of the reserved fields will be unreserved), so I'll adapt when we can adapt. The other thing not yet handled is automatic detection of a compressed image. We should be able to tell if the address passed is a gzip archive and if so, uncompress a block so we can tell where to decompress to. This however will open up the possibility of decompression overwriting ourselves unless we get loaded into a high enough location to start with. Coming up with a good default there will in turn require knowing how far another future change (randomization of text_offset, ala CONFIG_RANDOMIZE_BASE for x86 I imagine) can push where things may be. It's possible we'll just have to say for safety to do it as two steps, but we'll see.

Note that we also need do a fix in arch/arm/cpu/armv8/transition.S wrt cnthctl_el2 in that we shouldn't rely on a valid value to be in there at reset to orr against but instead set the values directly.

Signature · 1 line
Tom
author
#1 lore raw

RFC PATCH 1/4 arm64: Correct passing of Linux kernel args

The Documentation/arm64/booting.txt document says that pass in x1/x2/x3 as 0 as they are reserved for future use.

---
 arch/arm/lib/bootm.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
arch/arm/lib/bootm.c +5 -3
index 47ee070..0706086 100644
@@ -249,10 +249,12 @@ static void boot_prep_linux(bootm_headers_t *images)
 static void boot_jump_linux(bootm_headers_t *images, int flag)
 {
 #ifdef CONFIG_ARM64
-	void (*kernel_entry)(void *fdt_addr);
+	void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
+			void *res2);
 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
 
-	kernel_entry = (void (*)(void *fdt_addr))images->ep;
+	kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1,
+				void *res2))images->ep;
 
 	debug("## Transferring control to Linux (at address %lx)...\n",
 		(ulong) kernel_entry);
@@ -261,7 +263,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 	announce_and_cleanup(fake);
 
 	if (!fake)
-		kernel_entry(images->ft_addr);
+		kernel_entry(images->ft_addr, 0x0, 0x0, 0x0);
 #else
 	unsigned long machid = gd->bd->bi_arch_number;
 	char *s;
Signature · 1 line
1.7.9.5
author
#2 lore raw

RFC PATCH 2/4 cmd_bootm.c: Add 'booti' for ARM64 Linux kernel Images

In reply to Tom Rini

The default format for arm64 Linux kernels is the "Image" format, described in Documentation/arm64/booting.txt. This, along with an optional gzip compression on top is all that is generated by default. The Image format has a magic number within the header for verification, a text_offset where the Image must be run from and reserved fields.

This does not support automatic detection of a gzip compressed image.

---
 README             |    1 +
 common/cmd_bootm.c |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
README +1 -0
index 12758dc..e7c8b2e 100644
@@ -946,6 +946,7 @@ The following options need to be configured:
 		CONFIG_CMD_BMP		* BMP support
 		CONFIG_CMD_BSP		* Board specific commands
 		CONFIG_CMD_BOOTD	  bootd
+		CONFIG_CMD_BOOTI	* ARM64 Linux kernel Image support
 		CONFIG_CMD_CACHE	* icache, dcache
 		CONFIG_CMD_CLK   	* clock command support
 		CONFIG_CMD_CONSOLE	  coninfo
common/cmd_bootm.c +139 -0

142 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#3 lore raw

RFC PATCH 2/4 cmd_bootm.c: Add 'booti' for ARM64 Linux kernel Images

Quoted 19 lines · Tom Rini

The default format for arm64 Linux kernels is the "Image" format, described in Documentation/arm64/booting.txt. This, along with an optional gzip compression on top is all that is generated by default. The Image format has a magic number within the header for verification, a text_offset where the Image must be run from and reserved fields.

This does not support automatic detection of a gzip compressed image.

---
 README             |    1 +
 common/cmd_bootm.c |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
README +0 -0
index 12758dc..e7c8b2e 100644

README The following options need to be configured: · line 949

Quoted 4 lines
README +1 -0
@@ -946,6 +946,7 @@ The following options need to be configured:
                CONFIG_CMD_BMP          * BMP support
                CONFIG_CMD_BSP          * Board specific commands
                CONFIG_CMD_BOOTD          bootd
+               CONFIG_CMD_BOOTI        * ARM64 Linux kernel Image support

As I mentioned at ELC, I would prefer to see bootz and booti combined so we have a single "boot a plain kernel image" command. I'd rather see the command be smart enough to figure what the image is rather than the user have to figure out the right command. Of course with this argument, then everything should be a bootm command. IIRC, there would be some challenges to add bootz or booti functionality into bootm.

Quoted 46 lines
README +0 -0
                CONFIG_CMD_CACHE        * icache, dcache
                CONFIG_CMD_CLK          * clock command support
                CONFIG_CMD_CONSOLE        coninfo
common/cmd_bootm.c +35 -0
index c243a5b..3b9635c 100644
@@ -1929,3 +1929,142 @@ U_BOOT_CMD(
        "boot Linux zImage image from memory", bootz_help_text
 );
 #endif /* CONFIG_CMD_BOOTZ */
+
+#ifdef CONFIG_CMD_BOOTI
+/* See Documentation/arm64/booting.txt in the Linux kernel */
+struct Image_header {
+       uint32_t        code0;          /* Executable code */
+       uint32_t        code1;          /* Executable code */
+       uint64_t        text_offset;    /* Image load offset */
+       uint64_t        res0;           /* reserved */
+       uint64_t        res1;           /* reserved */
+       uint64_t        res2;           /* reserved */
+       uint64_t        res3;           /* reserved */
+       uint64_t        res4;           /* reserved */
+       uint32_t        magic;          /* Magic number */
+       uint32_t        res5;
+};
+
+#define LINUX_ARM64_IMAGE_MAGIC        0x644d5241
+/* XXX: Hack 16MB image size for now */
+#define HACK_ARM64_IMAGE_SIZE  (16 << 20)
+
+static int booti_setup(bootm_headers_t *images)
+{
+       struct Image_header *ih;
+       uint64_t dst;
+
+       ih = (struct Image_header *)map_sysmem(images->ep, 0);
+
+       if (ih->magic != LINUX_ARM64_IMAGE_MAGIC) {
+               puts("Bad Linux ARM64 Image magic!\n");
+               return 1;
+       }
+
+       /*
+        * If we are not at the correct run-time location, set the new
+        * correct location and then move the image there.

common/cmd_bootm.c U_BOOT_CMD( · line 1976

Quoted 10 lines
common/cmd_bootm.c +10 -0
+        */
+       dst = gd->bd->bi_dram[0].start + ih->text_offset;
+       if (images->ep != dst) {
+               void *src;
+
+               debug("Moving Image from 0x%lx to 0x%llx\n", images->ep, dst);
+
+               src = (void *)images->ep;
+               images->ep = dst;
+               memmove((void *)dst, src, HACK_ARM64_IMAGE_SIZE);

Don't you at least know the load size or the decompressed size? Only the .bss size is missing and you only need that to have some checks for overlapping images.

Rob

author
#4 lore raw

RFC PATCH 2/4 cmd_bootm.c: Add 'booti' for ARM64 Linux kernel Images

Quoted 25 lines · Rob Herring
Quoted 19 lines · Tom Rini

The default format for arm64 Linux kernels is the "Image" format, described in Documentation/arm64/booting.txt. This, along with an optional gzip compression on top is all that is generated by default. The Image format has a magic number within the header for verification, a text_offset where the Image must be run from and reserved fields.

This does not support automatic detection of a gzip compressed image.

---
 README             |    1 +
 common/cmd_bootm.c |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
README +0 -0
index 12758dc..e7c8b2e 100644

README The following options need to be configured: · line 949

Quoted 4 lines
README +1 -0
@@ -946,6 +946,7 @@ The following options need to be configured:
                CONFIG_CMD_BMP          * BMP support
                CONFIG_CMD_BSP          * Board specific commands
                CONFIG_CMD_BOOTD          bootd
+               CONFIG_CMD_BOOTI        * ARM64 Linux kernel Image support
Quoted 7 lines

As I mentioned at ELC, I would prefer to see bootz and booti combined so we have a single "boot a plain kernel image" command. I'd rather see the command be smart enough to figure what the image is rather than the user have to figure out the right command. Of course with this argument, then everything should be a bootm command. IIRC, there would be some challenges to add bootz or booti functionality into bootm.

Yes, this is an idea worth exploring.

Quoted 52 lines
Quoted 52 lines
README +0 -0
                CONFIG_CMD_CACHE        * icache, dcache
                CONFIG_CMD_CLK          * clock command support
                CONFIG_CMD_CONSOLE        coninfo
common/cmd_bootm.c +41 -0
index c243a5b..3b9635c 100644
@@ -1929,3 +1929,142 @@ U_BOOT_CMD(
        "boot Linux zImage image from memory", bootz_help_text
 );
 #endif /* CONFIG_CMD_BOOTZ */
+
+#ifdef CONFIG_CMD_BOOTI
+/* See Documentation/arm64/booting.txt in the Linux kernel */
+struct Image_header {
+       uint32_t        code0;          /* Executable code */
+       uint32_t        code1;          /* Executable code */
+       uint64_t        text_offset;    /* Image load offset */
+       uint64_t        res0;           /* reserved */
+       uint64_t        res1;           /* reserved */
+       uint64_t        res2;           /* reserved */
+       uint64_t        res3;           /* reserved */
+       uint64_t        res4;           /* reserved */
+       uint32_t        magic;          /* Magic number */
+       uint32_t        res5;
+};
+
+#define LINUX_ARM64_IMAGE_MAGIC        0x644d5241
+/* XXX: Hack 16MB image size for now */
+#define HACK_ARM64_IMAGE_SIZE  (16 << 20)
+
+static int booti_setup(bootm_headers_t *images)
+{
+       struct Image_header *ih;
+       uint64_t dst;
+
+       ih = (struct Image_header *)map_sysmem(images->ep, 0);
+
+       if (ih->magic != LINUX_ARM64_IMAGE_MAGIC) {
+               puts("Bad Linux ARM64 Image magic!\n");
+               return 1;
+       }
+
+       /*
+        * If we are not at the correct run-time location, set the new
+        * correct location and then move the image there.
+        */
+       dst = gd->bd->bi_dram[0].start + ih->text_offset;
+       if (images->ep != dst) {
+               void *src;
+
+               debug("Moving Image from 0x%lx to 0x%llx\n", images->ep, dst);
Quoted 8 lines

common/cmd_bootm.c U_BOOT_CMD( · line 1976

Quoted 4 lines
common/cmd_bootm.c +4 -0
+
+               src = (void *)images->ep;
+               images->ep = dst;
+               memmove((void *)dst, src, HACK_ARM64_IMAGE_SIZE);

Don't you at least know the load size or the decompressed size? Only the .bss size is missing and you only need that to have some checks for overlapping images.

No, we don't know for certain what the size is today. For example, my workflow is to load the kernel, load the dtb so filesize would have had the Image size, but then we've overwritten it. Since this information will be part of the header, so long as it's merged into the kernel soon I'm OK with saying at least this part of the series is just for RFC and people can apply it locally as needed. If we handled Image.gz we would know the decompress size but today I expect to handle Image.gz as a 2 step unzip and then booti. As I said in 0/4 I have some concern about doing it all as a single step, especially once randomized text offset happens (at least, depending on the range the offset could be within).

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140514/a202a24f/attachment.pgp>
author
#5 lore raw

RFC PATCH 3/4 vexpress_aemv8a.h: Clean up the config

In reply to Tom Rini

- Drop DEBUG
- Drop defines we can use the default of.
- Drop CONFIG_GICV3 and related defines, we aren't using interrupts and do not need to configure the interrupt controller.
- Provide a larger malloc pool.
- Correct default locations for kernel / initrd / device tree

---
 include/configs/vexpress_aemv8a.h |   26 +++++---------------------
 1 file changed, 5 insertions(+), 21 deletions(-)
include/configs/vexpress_aemv8a.h +5 -21
index dff6adc..ae0ee1b 100644
@@ -8,12 +8,8 @@
 #ifndef __VEXPRESS_AEMV8A_H
 #define __VEXPRESS_AEMV8A_H
 
-#define DEBUG
-
 #define CONFIG_REMAKE_ELF
 
-#define CONFIG_GICV3
-
 /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/
 
 /*#define CONFIG_SYS_GENERIC_BOARD*/
@@ -94,20 +90,11 @@
 /* Generic Timer Definitions */
 #define COUNTER_FREQUENCY		(0x1800000)	/* 24MHz */
 
-/* Generic Interrupt Controller Definitions */
-#ifdef CONFIG_GICV3
-#define GICD_BASE			(0x2f000000)
-#define GICR_BASE			(0x2f100000)
-#else
-#define GICD_BASE			(0x2C001000)
-#define GICC_BASE			(0x2C002000)
-#endif
-
 #define CONFIG_SYS_MEMTEST_START	V2M_BASE
 #define CONFIG_SYS_MEMTEST_END		(V2M_BASE + 0x80000000)
 
 /* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (8 << 20))
 
 /* SMSC91C111 Ethernet Configuration */
 #define CONFIG_SMC91111			1
@@ -121,7 +108,6 @@
 #define CONFIG_CONS_INDEX		0
 
 #define CONFIG_BAUDRATE			115200
-#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
 #define CONFIG_SYS_SERIAL0		V2M_UART0
 #define CONFIG_SYS_SERIAL1		V2M_UART1
 
@@ -166,10 +152,9 @@
 
 /* Initial environment variables */
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-					"kernel_addr=0x200000\0"	\
-					"initrd_addr=0xa00000\0"	\
-					"initrd_size=0x2000000\0"	\
-					"fdt_addr=0x100000\0"		\
+					"kernel_addr=0x80080000\0"	\
+					"initrd_addr=0x90000000\0"	\
+					"fdt_addr=0x88000000\0"		\
 					"fdt_high=0xa0000000\0"
 
 #define CONFIG_BOOTARGS			"console=ttyAMA0 root=/dev/ram0"
@@ -187,10 +172,9 @@
 #define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + \
 					sizeof(CONFIG_SYS_PROMPT) + 16)
 #define CONFIG_SYS_HUSH_PARSER
-#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
 #define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
 #define CONFIG_SYS_LONGHELP
-#define CONFIG_CMDLINE_EDITING		1
+#define CONFIG_CMDLINE_EDITING
 #define CONFIG_SYS_MAXARGS		64	/* max command args */
 
 #endif /* __VEXPRESS_AEMV8A_H */
Signature · 1 line
1.7.9.5
#6 lore raw

RFC PATCH 3/4 vexpress_aemv8a.h: Clean up the config

Quoted 9 lines · Tom Rini

- Drop DEBUG
- Drop defines we can use the default of.
- Drop CONFIG_GICV3 and related defines, we aren't using interrupts and do not need to configure the interrupt controller.
- Provide a larger malloc pool.
- Correct default locations for kernel / initrd / device tree

---

[...]

Quoted 7 lines
include/configs/vexpress_aemv8a.h +0 -2
-#define CONFIG_GICV3
-
 /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/
 
 /*#define CONFIG_SYS_GENERIC_BOARD*/
@@ -94,20 +90,11 @@
 /* Generic Timer Definitions */

include/configs/vexpress_aemv8a.h line 104

Quoted 10 lines
include/configs/vexpress_aemv8a.h +0 -8
 #define COUNTER_FREQUENCY              (0x1800000)     /* 24MHz */
 
-/* Generic Interrupt Controller Definitions */
-#ifdef CONFIG_GICV3
-#define GICD_BASE                      (0x2f000000)
-#define GICR_BASE                      (0x2f100000)
-#else
-#define GICD_BASE                      (0x2C001000)
-#define GICC_BASE                      (0x2C002000)
-#endif

IIRC, these should be needed if secure to non-secure switching is done.

include/configs/vexpress_aemv8a.h line 97

Quoted 6 lines
include/configs/vexpress_aemv8a.h +1 -1
 #define CONFIG_SYS_MEMTEST_START       V2M_BASE
 #define CONFIG_SYS_MEMTEST_END         (V2M_BASE + 0x80000000)
 
 /* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + 128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + (8 << 20))

This seems like another candidate for some sane default value.

Quoted 11 lines
include/configs/vexpress_aemv8a.h +0 -1
 /* SMSC91C111 Ethernet Configuration */
 #define CONFIG_SMC91111                        1
@@ -121,7 +108,6 @@
 #define CONFIG_CONS_INDEX              0
 
 #define CONFIG_BAUDRATE                        115200
-#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }
 #define CONFIG_SYS_SERIAL0             V2M_UART0
 #define CONFIG_SYS_SERIAL1             V2M_UART1
 

include/configs/vexpress_aemv8a.h line 157

Quoted 10 lines
include/configs/vexpress_aemv8a.h +3 -4
@@ -166,10 +152,9 @@
 
 /* Initial environment variables */
 #define CONFIG_EXTRA_ENV_SETTINGS      \
-                                       "kernel_addr=0x200000\0"        \
-                                       "initrd_addr=0xa00000\0"        \
-                                       "initrd_size=0x2000000\0"       \
-                                       "fdt_addr=0x100000\0"           \
+                                       "kernel_addr=0x80080000\0"      \
+                                       "initrd_addr=0x90000000\0"      \
+                                       "fdt_addr=0x88000000\0"         \

Don't we want the _r variants here?

Rob

author
#7 lore raw

RFC PATCH 3/4 vexpress_aemv8a.h: Clean up the config

Quoted 22 lines · Rob Herring
Quoted 9 lines · Tom Rini

- Drop DEBUG
- Drop defines we can use the default of.
- Drop CONFIG_GICV3 and related defines, we aren't using interrupts and do not need to configure the interrupt controller.
- Provide a larger malloc pool.
- Correct default locations for kernel / initrd / device tree

---

[...]

Quoted 9 lines
include/configs/vexpress_aemv8a.h +0 -2
-#define CONFIG_GICV3
-
 /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/
 
 /*#define CONFIG_SYS_GENERIC_BOARD*/
@@ -94,20 +90,11 @@
 /* Generic Timer Definitions */
 #define COUNTER_FREQUENCY              (0x1800000)     /* 24MHz */
 
Quoted 10 lines

include/configs/vexpress_aemv8a.h line 104

Quoted 8 lines
include/configs/vexpress_aemv8a.h +0 -8
-/* Generic Interrupt Controller Definitions */
-#ifdef CONFIG_GICV3
-#define GICD_BASE                      (0x2f000000)
-#define GICR_BASE                      (0x2f100000)
-#else
-#define GICD_BASE                      (0x2C001000)
-#define GICC_BASE                      (0x2C002000)
-#endif

IIRC, these should be needed if secure to non-secure switching is done.

Not something I can test so OK, I'll put that back next go-round.

Quoted 8 lines

include/configs/vexpress_aemv8a.h line 97

Quoted 6 lines
include/configs/vexpress_aemv8a.h +1 -1
 #define CONFIG_SYS_MEMTEST_START       V2M_BASE
 #define CONFIG_SYS_MEMTEST_END         (V2M_BASE + 0x80000000)
 
 /* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + 128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + (8 << 20))

This seems like another candidate for some sane default value.

Well, the previous value was relatively sane. It only needs bumping up beyond env + a bit of room if you:
- Have UBI/UBIFS
- Expect to use a decompressor.

The latter isn't that common, but if we start doing Image.gz more often might be. But it'll also be worth some quick benchmarking to see if it's any sort of time win or not.

Quoted 12 lines
Quoted 12 lines
include/configs/vexpress_aemv8a.h +0 -1
 /* SMSC91C111 Ethernet Configuration */
 #define CONFIG_SMC91111                        1
@@ -121,7 +108,6 @@
 #define CONFIG_CONS_INDEX              0
 
 #define CONFIG_BAUDRATE                        115200
-#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }
 #define CONFIG_SYS_SERIAL0             V2M_UART0
 #define CONFIG_SYS_SERIAL1             V2M_UART1
 
@@ -166,10 +152,9 @@
 
Quoted 11 lines

include/configs/vexpress_aemv8a.h line 157

Quoted 9 lines
include/configs/vexpress_aemv8a.h +3 -4
 /* Initial environment variables */
 #define CONFIG_EXTRA_ENV_SETTINGS      \
-                                       "kernel_addr=0x200000\0"        \
-                                       "initrd_addr=0xa00000\0"        \
-                                       "initrd_size=0x2000000\0"       \
-                                       "fdt_addr=0x100000\0"           \
+                                       "kernel_addr=0x80080000\0"      \
+                                       "initrd_addr=0x90000000\0"      \
+                                       "fdt_addr=0x88000000\0"         \

Don't we want the _r variants here?

Good point, need to sanitize that wrt doc/README.pxe and such.

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140514/03873329/attachment.pgp>
author
#8 lore raw

RFC PATCH 4/4 vexpress_aemv8a.h: Enable CONFIG_CMD_BOOTI and CONFIG_CMD_UNZIP

In reply to Tom Rini

Add support for booting Images and for unzipping Image.gz files.

---
 include/configs/vexpress_aemv8a.h |    2 ++
 1 file changed, 2 insertions(+)
include/configs/vexpress_aemv8a.h +2 -0
index ae0ee1b..aa64750 100644
@@ -116,6 +116,8 @@
 /*#define CONFIG_MENU_SHOW*/
 #define CONFIG_CMD_CACHE
 #define CONFIG_CMD_BDI
+#define CONFIG_CMD_BOOTI
+#define CONFIG_CMD_UNZIP
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_PXE
 #define CONFIG_CMD_ENV
Signature · 1 line
1.7.9.5