代码拉取完成,页面将自动刷新
From 40c03992bc470e29d0cc33e6f290916434092d76 Mon Sep 17 00:00:00 2001
From: Yuanhe Shu <xiangzao@linux.alibaba.com>
Date: Mon, 18 Sep 2023 19:48:50 +0800
Subject: [PATCH] Add pstore segment support
Add pstore segment thus it is able to record log of kdump process
Signed-off-by: Yuanhe Shu <xiangzao@linux.alibaba.com>
---
kexec/arch/arm64/crashdump-arm64.c | 5 ++
kexec/arch/i386/crashdump-x86.c | 12 ++++-
kexec/kexec.c | 80 ++++++++++++++++++++++++++++++
kexec/kexec.h | 5 ++
4 files changed, 100 insertions(+), 2 deletions(-)
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index 3098315..6aa954c 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -125,6 +125,11 @@ static int crash_get_memory_ranges(void)
if (!usablemem_rgns.size)
return -EINVAL;
+ usablemem_rgns.ranges[usablemem_rgns.size - 1].end -= PSTORE_SIZE;
+
+ dbgprintf("Created pstore segment at 0x%lx\n",
+ usablemem_rgns.ranges[usablemem_rgns.size - 1].end);
+
dbgprint_mem_range("Reserved memory range",
usablemem_rgns.ranges, usablemem_rgns.size);
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index df1f24c..3614007 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -823,7 +823,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
unsigned long max_addr, unsigned long min_base)
{
void *tmp;
- unsigned long sz, bufsz, memsz, elfcorehdr;
+ unsigned long sz, bufsz, memsz, elfcorehdr, pstore_sz, pstore_start;
int nr_ranges = 0, nr_memmap = 0, align = 1024, i;
struct memory_range *mem_range, *memmap_p;
struct crash_elf_info elf_info;
@@ -923,6 +923,14 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
}
}
+ pstore_sz = _ALIGN(PSTORE_SIZE, align);
+ pstore_start = (unsigned long)crash_reserved_mem[crash_reserved_mem_nr - 1].start;
+ dbgprintf("Created pstore segment at 0x%lx\n", pstore_start);
+ if (delete_memmap(memmap_p, &nr_memmap, pstore_start, pstore_sz) < 0) {
+ free(memmap_p);
+ return EFAILED;
+ }
+
/* Create elf header segment and store crash image data. */
if (arch_options.core_header_type == CORE_TYPE_ELF64) {
if (crash_create_elf64_headers(info, &elf_info, mem_range,
@@ -1004,7 +1012,7 @@ int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
if (!crash_reserved_mem_nr)
return -1;
- *start = crash_reserved_mem[crash_reserved_mem_nr - 1].start;
+ *start = crash_reserved_mem[crash_reserved_mem_nr - 1].start + PSTORE_SIZE;
*end = crash_reserved_mem[crash_reserved_mem_nr - 1].end;
return 0;
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 829a6ea..c1cb00e 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -40,6 +40,7 @@
#endif
#include <getopt.h>
#include <ctype.h>
+#include <elf.h>
#include "config.h"
@@ -638,6 +639,79 @@ char *slurp_decompress_file(const char *filename, off_t *r_size)
return kernel_buf;
}
+static int readlog(unsigned long long paddrbase)
+{
+ const char kcore[] = "/proc/kcore";
+ Elf64_Ehdr *elf64;
+ Elf64_Phdr *load64, *notes64, *lp64;
+ char eheader[MAX_KCORE_ELF_HEADER_SIZE], console_buf[1000000], tty_buf[100000];
+ int fd, i, segments;
+ unsigned long long console_offset, tty_offset, console_vaddr, tty_vaddr,
+ console_paddr, tty_paddr, page_offset;
+ const unsigned long long pud_mask = ~((1 << 30) - 1);
+
+ #ifdef __x86_64__
+ page_offset = 0;
+ #endif
+ #ifdef __aarch64__
+ page_offset = 0xfffeffffc0000000;
+ #endif
+ console_paddr = paddrbase + 0xe00c;
+ tty_paddr = paddrbase + 0x5000c;
+
+ if ((fd = open(kcore, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cannot open %s: %s\n", kcore, strerror(errno));
+ return -1;
+ }
+
+ if (read(fd, eheader, MAX_KCORE_ELF_HEADER_SIZE) != MAX_KCORE_ELF_HEADER_SIZE) {
+ fprintf(stderr, "Cannot read %s: %s\n", kcore, strerror(errno));
+ return -1;
+ }
+
+ elf64 = (Elf64_Ehdr *)&eheader[0];
+
+ notes64 = (Elf64_Phdr *)&eheader[elf64->e_phoff];
+ load64 = notes64 + 1;
+
+ segments = elf64->e_phnum - 1;
+
+ if (page_offset == 0) {
+ for ( i = 0; i < segments; i++) {
+ lp64 = load64 + i;
+ if (lp64->p_type == PT_LOAD)
+ if ((page_offset == 0) | page_offset > (lp64->p_vaddr & pud_mask))
+ page_offset = lp64->p_vaddr & pud_mask;
+ }
+ }
+ console_vaddr = console_paddr + page_offset;
+ tty_vaddr = tty_paddr + page_offset;
+
+ for ( i = 0; i < segments; i++) {
+ lp64 = load64 + i;
+ if ((console_vaddr >= lp64->p_vaddr) && (console_vaddr < (lp64->p_vaddr + lp64->p_memsz))) {
+ console_offset = console_vaddr - lp64->p_vaddr + lp64->p_offset;
+ tty_offset = tty_vaddr - lp64->p_vaddr + lp64->p_offset;
+ break;
+ }
+ }
+
+ memset(console_buf, 0, sizeof(console_buf));
+ memset(tty_buf, 0, sizeof(tty_buf));
+
+ off_t c_offset = lseek(fd, console_offset, SEEK_SET);
+ size_t c_size = read(fd, console_buf, 1000000);
+
+ off_t t_offset = lseek(fd, tty_offset, SEEK_SET);
+ size_t t_size = read(fd, tty_buf, 100000);
+
+ printf("console log: \n%s\nttylog:\n%s\n", console_buf, tty_buf);
+
+ close(fd);
+
+ return 0;
+}
+
static void update_purgatory(struct kexec_info *info)
{
static const uint8_t null_buf[256];
@@ -1016,6 +1090,7 @@ void usage(void)
"\n"
" -h, --help Print this help.\n"
" -v, --version Print the version of kexec.\n"
+ " -r, --read Print the logs of kdump process.\n"
" -f, --force Force an immediate kexec,\n"
" don't call shutdown.\n"
" -i, --no-checks Fast reboot, no memory integrity checks.\n"
@@ -1417,6 +1492,7 @@ int main(int argc, char *argv[])
int opt;
int result = 0;
int fileind;
+ unsigned long long phy_addr;
static const struct option options[] = {
KEXEC_ALL_OPTIONS
{ 0, 0, 0, 0},
@@ -1439,6 +1515,10 @@ int main(int argc, char *argv[])
case OPT_VERSION:
version();
return 0;
+ case OPT_READ:
+ phy_addr = strtoul(optarg, &endptr, 0);
+ readlog(phy_addr);
+ return 0;
case OPT_DEBUG:
kexec_debug = 1;
break;
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 8a05644..899f01b 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -232,9 +232,11 @@ extern int file_types;
#define OPT_LOAD_LIVE_UPDATE 263
#define OPT_EXEC_LIVE_UPDATE 264
#define OPT_MAX 265
+#define OPT_READ 266
#define KEXEC_OPTIONS \
{ "help", 0, 0, OPT_HELP }, \
{ "version", 0, 0, OPT_VERSION }, \
+ { "read", 1, 0, OPT_READ }, \
{ "force", 0, 0, OPT_FORCE }, \
{ "no-checks", 0, 0, OPT_NOCHECKS }, \
{ "no-ifdown", 0, 0, OPT_NOIFDOWN }, \
@@ -318,6 +320,9 @@ const char * proc_iomem(void);
#define MAX_LINE 160
+#define PSTORE_SIZE 0x60000
+#define MAX_KCORE_ELF_HEADER_SIZE (32768)
+
char *concat_cmdline(const char *base, const char *append);
void cmdline_add_liveupdate(char **base);
--
2.32.0 (Apple Git-132)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。