All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm64: Kexec: Add support for binary image
@ 2015-04-22 12:26 Pratyush Anand
  2015-04-22 12:26 ` [PATCH] arm64: kdump: " Pratyush Anand
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Pratyush Anand @ 2015-04-22 12:26 UTC (permalink / raw)
  To: kexec

This patch adds support to use binary image ie arch/arm64/boot/Image.

Binary image does not have sufficient knowledge to extract page offset
information, which is needed by kexec tool. Use a new command parameter
--page-offset, so that user can provide page offset information for
linear mapping.

Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 kexec/arch/arm64/include/arch/options.h | 10 ++--
 kexec/arch/arm64/kexec-arm64.c          |  3 ++
 kexec/arch/arm64/kexec-arm64.h          |  2 +
 kexec/arch/arm64/kexec-image-arm64.c    | 83 +++++++++++++++++++++++++++++++--
 4 files changed, 92 insertions(+), 6 deletions(-)

diff --git a/kexec/arch/arm64/include/arch/options.h b/kexec/arch/arm64/include/arch/options.h
index afe3e9827ff3..af14102220ea 100644
--- a/kexec/arch/arm64/include/arch/options.h
+++ b/kexec/arch/arm64/include/arch/options.h
@@ -5,9 +5,10 @@
 #define OPT_DTB		((OPT_MAX)+1)
 #define OPT_INITRD	((OPT_MAX)+2)
 #define OPT_LITE	((OPT_MAX)+3)
-#define OPT_PORT	((OPT_MAX)+4)
-#define OPT_REUSE_CMDLINE	((OPT_MAX+5))
-#define OPT_ARCH_MAX	((OPT_MAX)+6)
+#define OPT_PAGE_OFFSET	((OPT_MAX)+4)
+#define OPT_PORT	((OPT_MAX)+5)
+#define OPT_REUSE_CMDLINE	((OPT_MAX+6))
+#define OPT_ARCH_MAX	((OPT_MAX)+7)
 
 #define KEXEC_ARCH_OPTIONS \
 	KEXEC_OPTIONS \
@@ -16,6 +17,7 @@
 	{ "dtb",          1, NULL, OPT_DTB }, \
 	{ "initrd",       1, NULL, OPT_INITRD }, \
 	{ "lite",         0, NULL, OPT_LITE }, \
+	{ "page-offset",  1, NULL, OPT_PAGE_OFFSET }, \
 	{ "port",         1, NULL, OPT_PORT }, \
 	{ "ramdisk",      1, NULL, OPT_INITRD }, \
 	{ "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, \
@@ -30,6 +32,7 @@ static const char arm64_opts_usage[] __attribute__ ((unused)) =
 "     --dtb=FILE            Use FILE as the device tree blob.\n"
 "     --initrd=FILE         Use FILE as the kernel initial ramdisk.\n"
 "     --lite                Fast reboot, no memory integrity checks.\n"
+"     --page-offset         Kernel page-offset for binary image load.\n"
 "     --port=ADDRESS        Purgatory output to port ADDRESS.\n"
 "     --ramdisk=FILE        Use FILE as the kernel initial ramdisk.\n"
 "     --reuse-cmdline       Use command line arg of primary kernel.\n";
@@ -38,6 +41,7 @@ struct arm64_opts {
 	const char *command_line;
 	const char *dtb;
 	const char *initrd;
+	uint64_t page_offset;
 	uint64_t port;
 	int lite;
 };
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 6398e55fe575..86408598a465 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -100,6 +100,9 @@ int arch_process_options(int argc, char **argv)
 		case OPT_PORT:
 			arm64_opts.port = strtoull(optarg, NULL, 0);
 			break;
+		case OPT_PAGE_OFFSET:
+			arm64_opts.page_offset = strtoull(optarg, NULL, 0);
+			break;
 		default:
 			break; /* Ignore core and unknown options. */
 		}
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index 057acf313b49..7f0ca13fec11 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -17,6 +17,8 @@
 #define BOOT_BLOCK_LAST_COMP_VERSION 16
 #define COMMAND_LINE_SIZE 512
 
+#define ARM64_DEFAULT_PAGE_OFFSET 0xfffffe0000000000
+
 int elf_arm64_probe(const char *kernel_buf, off_t kernel_size);
 int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
 	off_t kernel_size, struct kexec_info *info);
diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
index b025dc6c0185..a52ef8ea7309 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -8,6 +8,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <libfdt.h>
+#include <stdlib.h>
 
 #include "dt-ops.h"
 #include "image-header.h"
@@ -31,15 +32,91 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size)
 	dbgprintf("%s: PE format: %s\n", __func__,
 		(arm64_header_check_pe_sig(h) ? "yes" : "no"));
 
-	fprintf(stderr, "kexec: arm64 binary Image files are currently NOT SUPPORTED.\n");
+	return 0;
+}
+
+static unsigned long long get_kernel_text_sym(void)
+{
+	const char *kallsyms = "/proc/kallsyms";
+	const char *text = "_text";
+	char sym[128];
+	char line[128];
+	FILE *fp;
+	unsigned long long vaddr;
+	char type;
 
-	return -1;
+	fp = fopen(kallsyms, "r");	if (!fp) {
+		fprintf(stderr, "Cannot open %s\n", kallsyms);
+		return 0;
+	}
+
+	while(fgets(line, sizeof(line), fp) != NULL) {
+		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
+			continue;
+		if (strcmp(sym, text) == 0) {
+			dbgprintf("kernel symbol %s vaddr = %16llx\n", text, vaddr);
+			return vaddr;
+		}
+	}
+
+	fprintf(stderr, "Cannot get kernel %s symbol address\n", text);
+	return 0;
+}
+
+static unsigned long long get_kernel_page_offset(void)
+{
+	unsigned long long text_sym_addr = get_kernel_text_sym();
+	unsigned long long text_page_offset =
+		text_sym_addr & 0xFFFFFFFFFFE00000;
+
+	if(arm64_opts.page_offset) {
+		if (text_page_offset != arm64_opts.page_offset)
+			dbgprintf("User page offset did not match with text page offset\n"); 
+		return arm64_opts.page_offset;
+	} else if(text_page_offset) {
+		dbgprintf("text page offset is %llx\n", text_page_offset);
+		return text_page_offset;
+	} else {
+		return ARM64_DEFAULT_PAGE_OFFSET;
+	}
 }
 
 int image_arm64_load(int argc, char **argv, const char *kernel_buf,
 	off_t kernel_size, struct kexec_info *info)
 {
-	return -ENOSYS;
+	int result;
+	uint64_t start;
+	const struct arm64_image_header *h;
+	char *header_option = NULL;
+
+	h = (const struct arm64_image_header *)(kernel_buf);
+
+	arm64_mem.text_offset = le64_to_cpu(h->text_offset);
+	arm64_mem.image_size = le64_to_cpu(h->image_size);
+
+	arm64_mem.page_offset = get_kernel_page_offset();
+
+	result = parse_iomem_single("Kernel code\n", &start, NULL);
+
+	if (result) {
+		fprintf(stderr, "kexec: Could not get kernel code address.\n");
+		return -1;
+	}
+	start -= arm64_mem.text_offset;
+
+	/* Add kernel */
+	add_segment_phys_virt(info, kernel_buf, kernel_size,
+			start + arm64_mem.text_offset,
+			kernel_size, 0);
+
+	info->entry = (void *)start + arm64_mem.text_offset;
+
+	result = arm64_load_other_segments(info, (unsigned long)info->entry);
+
+	if (header_option)
+		free(header_option);
+
+	return result;
 }
 
 void image_arm64_usage(void)
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH] arm64: kdump: Add support for binary image
  2015-04-22 12:26 [PATCH] arm64: Kexec: Add support for binary image Pratyush Anand
@ 2015-04-22 12:26 ` Pratyush Anand
  2015-04-22 12:26 ` [PATCH] arm64: wait for transmit completion before next character transmission Pratyush Anand
  2015-05-06 17:34 ` [PATCH] arm64: Kexec: Add support for binary image Geoff Levand
  2 siblings, 0 replies; 5+ messages in thread
From: Pratyush Anand @ 2015-04-22 12:26 UTC (permalink / raw)
  To: kexec

This patch adds support to use binary image ie arch/arm64/boot/Image
with kdump.

Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 kexec/arch/arm64/kexec-image-arm64.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
index a52ef8ea7309..1f5395bdfabf 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -10,6 +10,7 @@
 #include <libfdt.h>
 #include <stdlib.h>
 
+#include "crashdump-arm64.h"
 #include "dt-ops.h"
 #include "image-header.h"
 #include "kexec-arm64.h"
@@ -96,13 +97,23 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf,
 
 	arm64_mem.page_offset = get_kernel_page_offset();
 
-	result = parse_iomem_single("Kernel code\n", &start, NULL);
+	if (info->kexec_flags & KEXEC_ON_CRASH) {
+		result = load_crashdump_segments(info, &header_option);
 
-	if (result) {
-		fprintf(stderr, "kexec: Could not get kernel code address.\n");
-		return -1;
+		if (result) {
+			fprintf(stderr, "kexec: load crashdump segments failed.\n");
+			return -1;
+		}
+		start = crash_reserved_mem.start;
+	} else {
+		result = parse_iomem_single("Kernel code\n", &start, NULL);
+
+		if (result) {
+			fprintf(stderr, "kexec: Could not get kernel code address.\n");
+			return -1;
+		}
+		start -= arm64_mem.text_offset;
 	}
-	start -= arm64_mem.text_offset;
 
 	/* Add kernel */
 	add_segment_phys_virt(info, kernel_buf, kernel_size,
@@ -111,7 +122,8 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf,
 
 	info->entry = (void *)start + arm64_mem.text_offset;
 
-	result = arm64_load_other_segments(info, (unsigned long)info->entry);
+	result = arm64_load_other_segments(info, (unsigned long)info->entry,
+		header_option);
 
 	if (header_option)
 		free(header_option);
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH] arm64: wait for transmit completion before next character transmission
  2015-04-22 12:26 [PATCH] arm64: Kexec: Add support for binary image Pratyush Anand
  2015-04-22 12:26 ` [PATCH] arm64: kdump: " Pratyush Anand
@ 2015-04-22 12:26 ` Pratyush Anand
  2015-05-06 17:34 ` [PATCH] arm64: Kexec: Add support for binary image Geoff Levand
  2 siblings, 0 replies; 5+ messages in thread
From: Pratyush Anand @ 2015-04-22 12:26 UTC (permalink / raw)
  To: kexec

Previous transmission must be completed before next character to be
transmitted, otherwise TX buffer may saturate and we will not see all
the characters on screen.

Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 purgatory/arch/arm64/purgatory-arm64.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/purgatory/arch/arm64/purgatory-arm64.c b/purgatory/arch/arm64/purgatory-arm64.c
index 25960c30bd05..3a1c9243bfa2 100644
--- a/purgatory/arch/arm64/purgatory-arm64.c
+++ b/purgatory/arch/arm64/purgatory-arm64.c
@@ -11,15 +11,37 @@ extern uint32_t *arm64_sink;
 extern void (*arm64_kernel_entry)(uint64_t);
 extern uint64_t arm64_dtb_addr;
 
+static void wait_for_xmit_complete(void)
+{
+	volatile uint32_t status;
+	volatile uint32_t *status_reg;
+
+	/*
+	 * Since most of the UART with ARM platform has LSR register at
+	 * offset 0x14 and should have value as 0x60 for TX empty, so we
+	 * have hardcoded these values. Can modify in future if need
+	 * arises.
+	 */
+	status_reg = (volatile uint32_t *)((uint64_t)arm64_sink + 0x14);
+	while (1) {
+		status = *status_reg;
+		if ((status & 0x60) == 0x60)
+			break;
+	}
+}
+
 void putchar(int ch)
 {
 	if (!arm64_sink)
 		return;
 
+	wait_for_xmit_complete();
 	*arm64_sink = ch;
 
-	if (ch == '\n')
+	if (ch == '\n') {
+		wait_for_xmit_complete();
 		*arm64_sink = '\r';
+	}
 }
 
 void setup_arch(void)
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] arm64: Kexec: Add support for binary image
  2015-04-22 12:26 [PATCH] arm64: Kexec: Add support for binary image Pratyush Anand
  2015-04-22 12:26 ` [PATCH] arm64: kdump: " Pratyush Anand
  2015-04-22 12:26 ` [PATCH] arm64: wait for transmit completion before next character transmission Pratyush Anand
@ 2015-05-06 17:34 ` Geoff Levand
  2015-05-14  5:12   ` Pratyush Anand
  2 siblings, 1 reply; 5+ messages in thread
From: Geoff Levand @ 2015-05-06 17:34 UTC (permalink / raw)
  To: Pratyush Anand; +Cc: kexec

Hi,

On Wed, 2015-04-22 at 17:56 +0530, Pratyush Anand wrote:

> @@ -30,6 +32,7 @@ static const char arm64_opts_usage[] __attribute__ ((unused)) =
>  "     --dtb=FILE            Use FILE as the device tree blob.\n"
>  "     --initrd=FILE         Use FILE as the kernel initial ramdisk.\n"
>  "     --lite                Fast reboot, no memory integrity checks.\n"
> +"     --page-offset         Kernel page-offset for binary image load.\n"

Sorry I didn't see this before, but page-offset is for Image load, so
should go in the image_arm64_usage().

I think it is OK to keep page_offset in struct arm64_opts, then just
ignore it for the other file formats.

>  "     --port=ADDRESS        Purgatory output to port ADDRESS.\n"
>  "     --ramdisk=FILE        Use FILE as the kernel initial ramdisk.\n"
>  "     --reuse-cmdline       Use command line arg of primary kernel.\n";

> --- a/kexec/arch/arm64/kexec-image-arm64.c
> +++ b/kexec/arch/arm64/kexec-image-arm64.c
> +static unsigned long long get_kernel_page_offset(void)
> +{
> +	unsigned long long text_sym_addr = get_kernel_text_sym();
> +	unsigned long long text_page_offset =
> +		text_sym_addr & 0xFFFFFFFFFFE00000;
> +
> +	if(arm64_opts.page_offset) {
> +		if (text_page_offset != arm64_opts.page_offset)
> +			dbgprintf("User page offset did not match with text page offset\n"); 

I'd like to see the values printed.

> +		return arm64_opts.page_offset;
> +	} else if(text_page_offset) {
> +		dbgprintf("text page offset is %llx\n", text_page_offset);
> +		return text_page_offset;
> +	} else {
> +		return ARM64_DEFAULT_PAGE_OFFSET;
> +	}
>  }

-Geoff



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] arm64: Kexec: Add support for binary image
  2015-05-06 17:34 ` [PATCH] arm64: Kexec: Add support for binary image Geoff Levand
@ 2015-05-14  5:12   ` Pratyush Anand
  0 siblings, 0 replies; 5+ messages in thread
From: Pratyush Anand @ 2015-05-14  5:12 UTC (permalink / raw)
  To: Geoff Levand; +Cc: kexec

Hi Geoff,

Thanks for the review.

On Wednesday 06 May 2015 11:04 PM, Geoff Levand wrote:
> Hi,
>
> On Wed, 2015-04-22 at 17:56 +0530, Pratyush Anand wrote:
>
>> @@ -30,6 +32,7 @@ static const char arm64_opts_usage[] __attribute__ ((unused)) =
>>   "     --dtb=FILE            Use FILE as the device tree blob.\n"
>>   "     --initrd=FILE         Use FILE as the kernel initial ramdisk.\n"
>>   "     --lite                Fast reboot, no memory integrity checks.\n"
>> +"     --page-offset         Kernel page-offset for binary image load.\n"
>
> Sorry I didn't see this before, but page-offset is for Image load, so
> should go in the image_arm64_usage().
>

OK, will modify.

> I think it is OK to keep page_offset in struct arm64_opts, then just
> ignore it for the other file formats.
>

Since arm64_opts.page_offset is used by only binary image file format, 
so should be OK.

>>   "     --port=ADDRESS        Purgatory output to port ADDRESS.\n"
>>   "     --ramdisk=FILE        Use FILE as the kernel initial ramdisk.\n"
>>   "     --reuse-cmdline       Use command line arg of primary kernel.\n";
>
>> --- a/kexec/arch/arm64/kexec-image-arm64.c
>> +++ b/kexec/arch/arm64/kexec-image-arm64.c
>> +static unsigned long long get_kernel_page_offset(void)
>> +{
>> +	unsigned long long text_sym_addr = get_kernel_text_sym();
>> +	unsigned long long text_page_offset =
>> +		text_sym_addr & 0xFFFFFFFFFFE00000;
>> +
>> +	if(arm64_opts.page_offset) {
>> +		if (text_page_offset != arm64_opts.page_offset)
>> +			dbgprintf("User page offset did not match with text page offset\n");
>
> I'd like to see the values printed.

OK, will modify.

~Pratyush

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-05-14  5:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-22 12:26 [PATCH] arm64: Kexec: Add support for binary image Pratyush Anand
2015-04-22 12:26 ` [PATCH] arm64: kdump: " Pratyush Anand
2015-04-22 12:26 ` [PATCH] arm64: wait for transmit completion before next character transmission Pratyush Anand
2015-05-06 17:34 ` [PATCH] arm64: Kexec: Add support for binary image Geoff Levand
2015-05-14  5:12   ` Pratyush Anand

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.