On 2017/3/17 22:25, Dave Anderson wrote: > > ----- Original Message ----- >> However, that is why I am interested in your live system initialization >> of kimage_voffset -- for live system access using /dev/mem, /proc/kcore, >> or an older version of the /dev/crash driver that did not have the ioctl() >> to read kimage_voffset. But, in order to do that, arm64_calc_kimage_voffset() >> needs to be able to handle all /proc/iomem cases to correctly calculate >> PHYS_OFFSET. > Or better stated, your arm64_calc_kimage_voffset() needs to be able to handle all > /proc/iomem cases to correctly calculate kimage_voffset. Because on the 4.8 > kernel, it does not work. > > Dave > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility Dave, Sorry for my misunderstanding of PHYS_OFFSET, actually kimage_voffset is the offset between kernel virtual address and physical address. So, to calculate it need find out which physical address is mapping to VA_START, not PHYS_OFFSET. Please check patch v5, it should be OK for live system. Thanks, Yueyi
From e25004764456e20d8121f9ccc105fb7d408f1948 Mon Sep 17 00:00:00 2001 From: Yueyi Li <liyueyi@xxxxxxxx> Date: Tue, 14 Mar 2017 21:25:21 +0800 Subject: [PATCH] [ARM64][patch] Auto calculate kimage_voffset by kaslr offset ARM64 kimage_voffset can be calculated if kernel ASLR offset is known. Add a function to auto calculate kimage_voffset when '--kaslr=<offset>' was set. --- arm64.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/arm64.c b/arm64.c index 6eaf96d..01e43e5 100644 --- a/arm64.c +++ b/arm64.c @@ -27,6 +27,7 @@ static struct machine_specific arm64_machine_specific = { 0 }; static int arm64_verify_symbol(const char *, ulong, char); static void arm64_parse_cmdline_args(void); +static void arm64_calc_kimage_voffset(void); static void arm64_calc_phys_offset(void); static void arm64_calc_virtual_memory_ranges(void); static int arm64_kdump_phys_base(ulong *); @@ -324,6 +325,9 @@ arm64_init(int when) machdep->init_kernel_pgd = arm64_init_kernel_pgd; /* use machdep parameters */ + arm64_calc_kimage_voffset(); + + /* use machdep parameters */ arm64_calc_phys_offset(); if (CRASHDEBUG(1)) { @@ -735,6 +739,83 @@ arm64_parse_cmdline_args(void) } } +static void +arm64_calc_kimage_voffset(void) +{ + struct machine_specific *ms = machdep->machspec; + ulong offset; + + if (ms->kimage_voffset) /* vmcoreinfo or --machdep override */ + return; + + if (!(kt->flags2 & KASLR) || !(kt->flags & RELOC_SET)) /*Calculate kiamge_voffset when KASLR enabled.*/ + return; + + if(ACTIVE()){ + char buf[BUFSIZE]; + char *p1; + int errflag; + FILE *iomem; + ulong kernel_code_range; + ulong memory_end; + ulong memory_start; + + if ((iomem = fopen("/proc/iomem", "r")) == NULL) + return; + + kernel_code_range = symbol_value("__init_begin") - symbol_value("_text"); + + errflag = 1; + while (fgets(buf, BUFSIZE, iomem)) { + if (strstr(buf, ": System RAM")) { + clean_line(buf); + + /*get end address of system ram region*/ + if (!(p1 = strstr(buf, ":"))) + continue; + *(p1-1) = NULLCHAR; + if (!(p1 = strstr(buf, "-"))) + continue; + memory_end = htol(p1+1, RETURN_ON_ERROR | QUIET, NULL); + if (BADADDR == memory_end) + continue; + + /*get start address of system ram region*/ + *p1 = NULLCHAR; + memory_start = htol(buf, RETURN_ON_ERROR | QUIET, NULL); + if (BADADDR == memory_start) + continue; + + /* system ram region is too small to load kernel code, find next region*/ + if((memory_end - memory_start) < kernel_code_range) + continue; + + errflag = 0; + break; + } + } + fclose(iomem); + + if (errflag) + return; + + offset = memory_start; + }else if (DISKDUMP_DUMPFILE()) + return; + else if (KDUMP_DUMPFILE()) + arm_kdump_phys_base(&offset); /*Get start address of first memory block*/ + else{ + error(WARNING, + "kimage_voffset cannot be determined from the dumpfile.\n"); + error(CONT, + "Using default value of 0. If this is not correct, then try\n"); + error(CONT, + "using the command line option: --machdep kimage_voffset=<addr>\n"); + return; + } + + ms->kimage_voffset = ms->vmalloc_start_addr + (kt->relocate * -1) - offset; +} static void arm64_calc_phys_offset(void) @@ -817,6 +898,7 @@ arm64_calc_phys_offset(void) } + /* * Determine PHYS_OFFSET either by reading VMCOREINFO or the kernel * symbol, otherwise borrow the 32-bit ARM functionality. -- 1.9.1
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility