Hello Liu,
That works -- but I think the addition of the next_symbol_value() function
is over-kill, and it introduces an unnecessary (although presumably impossible)
FATAL error. Why not simplify it to do something like this:
if ((string = pc->read_vmcoreinfo("CONFIG_ARM_LPAE"))) {
machdep->flags |= PAE;
free(string);
} else if ((sp = next_symbol("swapper_pg_dir")) &&
(sp->value - symbol_value("swapper_pg_dir")) == 0x5000))
machdep->flags |= PAE;
Thanks,
Dave
----- Original Message -----
Thanks to Dave's suggest, I impove the way to identify
LPAE enabled kernel for arm platform, for compatibility with
some old kernel.
If a vmcore santisfy one of the following conditions, It must
be generated by a LPAE enabled kernel.
(1) it has CONFIG_ARM_LPAE=y vmcore_info
(2) swapper_pg_dir and its next symbol value differ by 0x5000
Signed-off-by: Liu Hua <sdu.liu(a)huawei.com>
---
arm.c | 11 ++++++++++-
symbols.c | 10 ++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arm.c b/arm.c
index cb7d841..76ba699 100644
--- a/arm.c
+++ b/arm.c
@@ -190,6 +190,8 @@ void
arm_init(int when)
{
ulong vaddr;
+ char *string;
+ ulong difference;
#if defined(__i386__) || defined(__x86_64__)
if (ACTIVE())
@@ -229,8 +231,15 @@ arm_init(int when)
* LPAE requires an additional page for the PGD,
* so PG_DIR_SIZE = 0x5000 for LPAE
*/
- if ((symbol_value("_text") - symbol_value("swapper_pg_dir")) ==
0x5000)
+ if ((string = pc->read_vmcoreinfo("CONFIG_ARM_LPAE"))) {
machdep->flags |= PAE;
+ free(string);
+ } else {
+ difference = next_symbol_value("swapper_pg_dir", NULL)
+ - symbol_value("swapper_pg_dir");
+ if (difference == 0x5000)
+ machdep->flags |= PAE;
+ }
machdep->kvbase = symbol_value("_stext") & ~KVBASE_MASK;
machdep->identity_map_base = machdep->kvbase;
machdep->is_kvaddr = arm_is_kvaddr;
diff --git a/symbols.c b/symbols.c
index a0f256e..b294cd2 100644
--- a/symbols.c
+++ b/symbols.c
@@ -4936,6 +4936,16 @@ try_get_symbol_data(char *symbol, long size, void
*local)
return FALSE;
}
+ulong
+next_symbol_value(char *symbol, struct syment *psb)
+{
+ struct syment *sp;
+
+ if (!(sp = next_symbol(symbol, psb)))
+ error(FATAL, "cannot resolve \"%s\"\n", symbol);
+ return(sp->value);
+}
+
/*
* Return the value of a given symbol.
*/
--
1.9.0