Subject: Post mortem of a LKM
To: None <port-arm32@netbsd.org>
From: Charles M. Hannum <root@ihack.net>
List: port-arm32
Date: 12/06/1998 04:22:24
So I looked into why LKMs have been losing on the Shark.  The problem
is this:

Normal code for the ARM is compiled with branch instructions that take
a signed 26-bit offset.  This gives you a 64MB range, which is enough
for almost all programs.  However, in the case of a LKM:

* The kernel is loaded at VA f0000000.

* In a normal configuration, a module gets loaded fairly high in
  memory -- in my case, at f327a000.

Obviously, if the LKM tries to make branches/calls into the base
kernel code, this blows chunks.  It just so happens that it loses
immediately on loading most modules -- rather than calling lkm_nofunc,
it ends up at lkm_nofunc+64MB.

There are two ways to fix this:

* Arrange for the modules to be loaded closer to the kernel text.

* Compile modules as quasi-PIC -- namely, put all external references
  into the constant pool, so they can be fixed up with 32-bit offsets
  at link time.

Unfortunately, both of these are vaguely hairy to implement...