On Wed, Jan 03, 2007 at 09:29:52AM -0500, Dave Anderson wrote:
>
> WARNING: invalid linux_banner pointer: 756e694c
> crash: vmlinux and vmcore do not match!
>
Hi Vivek,
It has to do with how the linux_banner symbol is declared. The crash code
in question does this:
if (!(sp = symbol_search("linux_banner")))
error(FATAL, "linux_banner symbol does not exist?\n");
else if (sp->type == 'R')
linux_banner = symbol_value("linux_banner");
else
get_symbol_data("linux_banner", sizeof(ulong),
&linux_banner);
if (!IS_KVADDR(linux_banner))
error(WARNING, "invalid linux_banner pointer: %lx\n",
linux_banner);
Up until 2.6.20-rc2 (apparently), if the linux_banner symbol
was in the readonly section ('R'), the string data was located
at the address of the linux_banner symbol. Otherwise, the
linux_banner symbol contained the address of the string data.
In your kernel, what does "nm -Bn vmlinux | grep linux_banner" show?
Maybe 'r' instead of 'R'?
Hi Dave,
You are right. Following is "nm -Bn vmlinux | grep linux_banner" output.
c0411000 r linux_banner
I checked that in 2.6.19, following was definition of linux_banner.
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY
"@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION
"\n";
Symbol table entry for linux_banner:
c0407000 129 OBJECT GLOBAL DEFAULT 3 linux_banner
But in 2.6.20-rc, it has been made static. Hence scope of this symbol is no
more global and now it is local, hence 'r' instead of 'R'.
static const char linux_banner[] =
"Linux version " UTS_RELEASE
" (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
" (" LINUX_COMPILER ")"
" " UTS_VERSION "\n";
Symbol table entry for linux_banner:
c0411000 143 OBJECT LOCAL DEFAULT 7 linux_banner
Attached test patch works for me.
Just a thought, can debug info section tell us what is the type of
linux_banner? I mean something to differentiate between above two cases
where linux_banner itself is a string or it contains a pointer to string.
Thanks
Vivek
Signed-off-by: Vivek Goyal <vgoyal(a)in.ibm.com>
---
kernel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff -puN kernel.c~crash-unable-to-read-linux-banner-fix kernel.c
--- crash-4.0-3.16/kernel.c~crash-unable-to-read-linux-banner-fix 2007-01-04
14:05:23.000000000 +0530
+++ crash-4.0-3.16-root/kernel.c 2007-01-04 14:07:15.000000000 +0530
@@ -480,7 +480,7 @@ verify_version(void)
if (!(sp = symbol_search("linux_banner")))
error(FATAL, "linux_banner symbol does not exist?\n");
- else if (sp->type == 'R')
+ else if ((sp->type == 'R') || (sp->type == 'r'))
linux_banner = symbol_value("linux_banner");
else
get_symbol_data("linux_banner", sizeof(ulong), &linux_banner);
_