[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [microblaze-uclinux] Microblaze with MMU, loadable module printk problems



Jeff,

I've confirmed your report and discovered the cause - as a workaround can you please comment out the following line in

arch/microblaze/kernel/module.c, around line 100

                case R_MICROBLAZE_64:
                        old_value = ((location[0] & 0x0000FFFF) << 16) |
                                        (location[1] & 0x0000FFFF);
                        //value += old_value;
^^^^^ COMMENT OUT THIS LINE ^^^^^^^^^
                        location[0] = (location[0] & 0xFFFF0000) |

and give it a try?

With this fixup I get the correct module behaviour, both the printk()s and /proc entry.

The reason for this is a change between how mb-gcc handles ELF relocations from the previous (pre-mmu) to new (post-mmu) versions.

This issue has caused various amounts of pain over the years, and I'm sorry to see it return.

The "value += oldvalue" code was previously required because the compiler/linker split relocations between the code itself (embedding non-zero offsets in the opcodes) and the ELF relocation table (typically the offset of the .rodata section, for example).

Because of this splitting, we had to crack open the opcode from .text, add in the offset from the reloc table, then munge it back into .text to generate the fixed relocation.

However, now it seems that the complete relocation is stored in the reloc table. This would be great, *if* the compiler inserted zero offsets in the opcodes. But it doesn't - they're still in there - grrr!

So, we have to just ignore the "oldvalue", and put the new (reloc) value straight in.

The problem is that this is compiler dependent, I don't like the idea of an #ifdef on compiler version in module.c

I'll have a chat to the toolchain folks at Xilinx and see about the best way forward. Ideally we can just have the zero value offsets put into the opcodes, that way no workaround will be required. But, maybe there's some gcc/ld thing I'm missing that makes this the Right Way to do things.

Thanks for your patience and helpful test case.

John


jeffrey.fuller@xxxxxxxxx wrote:

John, thanks for the help. I had erred in saying that the driver would not do printks correctly on non-MMU Microblaze. The module you sent prints correctly and so do ones I build (long story short: I fooled myself into thinking the same problem was on both non-MMU and MMU).

However, we do still have a problem on Microblaze with MMU, and today we discovered something interesting by accident. This can be recreated with the following code and method:

CODE:
============
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>

#define STRING1 "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n"
#define STRING2 "a b c d e f g h i j  k  l  m  n  o  p  q  r  s  t \n"

static int __init
NspbInit(void)
{
    printk("%s", STRING1);
    printk("%s", STRING2);
    return 0;
}

module_init(NspbInit);

static void __exit
NspbCleanup(void)
{

}

module_exit(NspbCleanup);
============

METHOD:
Note: You must run this on a Microblaze w/ MMU in order to duplicate:

1. Build the above module with the mb-linux-gcc compiler (as I understand it, this is the compiler that should be used for Microblaze w/ MMU).

2. insmod the resulting module.

3. Expected output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
a b c d e f g h i j  k  l  m  n  o  p  q  r  s  t

4. Actual output:
 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

5. Now, build the above module with the microblaze-uclinux-gcc (as I understand it, this is the compiler that should be used for NON-MMU Microblaze).

6. insmod the resulting module.

7. You get the expected output.

So, in conclusion, when building a module for Microblaze w/ MMU and using the mb-linux-gcc compiler, which is the compiler we thought should be used, we get incorrect results. When using the microblaze-uclinux-gcc, we get expected results. Again, to reiterate, this is all on Microblaze w/ MMU. One further note: in our experience, just about any combination of printks and strings (including, for example printk("This is a string\n") should have problems when compiled with mb-linux-gcc, though we have seen a few simple, single strings print correctly.

Can anyone tell me if we've somehow got our understanding of the compilers mixed up? Or is there a real bug here? Can anyone try the above test code and method on a Microbaze MMIU? Any help would be greatly appreciated.

Regards,
Jeff

*Jeff Fuller*
Software Engineer
EI WW SOFTWARE SYSTEMS ENGINEERING

Eastman Kodak Company
2400 Mt Read Blvd.
Rochester, NY 14650-3019
_
__jeffrey.fuller@xxxxxxxxxx <mailto:jeffrey.fuller@xxxxxxxxx>
Office: (585)726-6908 _
__www.kodak.com_ <http://www.kodak.com/>



*John Williams <jwilliams@xxxxxxxxxxxxxx>*
Sent by: owner-microblaze-uclinux@xxxxxxxxxxxxxx

05/11/2008 07:38 PM
Please respond to
microblaze-uclinux@xxxxxxxxxxxxxx


	
To
	microblaze-uclinux@xxxxxxxxxxxxxx
cc
	
Subject
Re: [microblaze-uclinux] Microblaze with MMU, loadable module printk problems


	





Hi Jeff,

jeffrey.fuller@xxxxxxxxx wrote:

 > An update on this problem. I tried running with v0.30 of the Petalinux
 > distro uclinux (non-MMU microblaze) and got the same problem. I also
 > modified the rng-core.ko module (random number driver) included in the
 > Petalinux Microblaze with MMU v0.10 to include some printks, then used
 > make "menuconfig" to turn the build of the module on. I then loaded the
 > resulting module using insmod. The output of the printks was incorrect.
 >
 > So, what I am seeing so far is that I am unable to get reliable output
 > from loadable modules running on Microblaze. This includes modules that
 > I didn't write and that I didn't compile (i.e. makefiles for the
 > rng-core.ko module were part of the distro). Has anyone else actually
 > seen valid printk or /proc output from a loadable module running on
 > Microblaze? My next step might be to compile my driver into the kernel
 > and see if printks work then.

Here's what I get on a board here (noMMU) running petalinux-v0.30-rc1
(with a few additions, but nothing that should relate to modules).

# insmod ./modtest.ko
Using ./modtest.ko
modtest: module license 'unspecified' taints kernel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
a b c d e f g h i j  k  l  m  n  o  p  q  r  s  t

All looks fine.

Here are my busybox insmod configs:

CONFIG_USER_BUSYBOX_INSMOD=y
CONFIG_USER_BUSYBOX_LSMOD=y
CONFIG_USER_BUSYBOX_MODPROBE=y
CONFIG_USER_BUSYBOX_RMMOD=y
# CONFIG_USER_BUSYBOX_2_2_MODULES is not set
CONFIG_USER_BUSYBOX_2_4_MODULES=y
CONFIG_USER_BUSYBOX_2_6_MODULES=y
# CONFIG_USER_BUSYBOX_INSMOD_VERSION_CHECKING is not set
CONFIG_USER_BUSYBOX_CHECK_TAINTED_MODULE=y
# CONFIG_USER_BUSYBOX_INSMOD_LOADINKMEM is not set
CONFIG_USER_BUSYBOX_INSMOD_KSYMOOPS_SYMBOLS=y
# CONFIG_USER_BUSYBOX_INSMOD_LOAD_MAP is not set

I've attached the module binary I built and loaded - maybe you can give
it a try on your board (noMMU).  CPU settings are

CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1
CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
CONFIG_XILINX_MICROBLAZE0_USE_DIV=1
CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=1
CONFIG_XILINX_MICROBLAZE0_USE_FPU=0

yours will need to match or it will not work - I can rebuild with a
subset if you like.

I'll test it on an MMU boot when I get the chance - Michal maybe you can
give it a try if you have one handy?

Regards,

John



[attachment "modtest.ko" deleted by Jeffrey J. Fuller/470335/EKC]


___________________________
microblaze-uclinux mailing list
microblaze-uclinux@xxxxxxxxxxxxxx
Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/