| 1 |
New kmod IPKG creation style |
|---|
| 2 |
============================ |
|---|
| 3 |
|
|---|
| 4 |
The KMOD_template is a PITA. Having an automated algorithm to create the IPKG |
|---|
| 5 |
files from the built kernel modules is a lot better way of doing it. Following |
|---|
| 6 |
the KISS principle, let's simply create one IPKG per module, extracting all |
|---|
| 7 |
necessary information right out of the module itself. |
|---|
| 8 |
|
|---|
| 9 |
PKGNAME="kmod-${FILENAME%%.ko}" |
|---|
| 10 |
FILENAME="${PKGNAME}.ipk" |
|---|
| 11 |
DESCR="`modinfo ${FILENAME} | grep description | sed 's/description: //'`" |
|---|
| 12 |
DEPENDS="kernel (${BOARD}-${KERNEL}-${LINUX_VERSION}) \ |
|---|
| 13 |
`modinfo ${FILENAME} | grep depends | sed 's/depends: //'`" |
|---|
| 14 |
|
|---|
| 15 |
There is one major problem left: the ADK never enables modular kernel features |
|---|
| 16 |
for being built into the kernel binary, they always end up as modules. The |
|---|
| 17 |
decision of the user of whether a certain kernel feature is "m" or "y" just |
|---|
| 18 |
decides whether the module is being shipped with the generated image or not. |
|---|
| 19 |
|
|---|
| 20 |
This is where the problems start: since for every built module the decision |
|---|
| 21 |
has to be made of whether it has to be built into the image or not, there has |
|---|
| 22 |
to be knowledge about the corresponding kernel config symbol's value. But it's |
|---|
| 23 |
not the value, it's the symbol: Actually, it's non-trivial to find out which |
|---|
| 24 |
kernel config symbol triggered the creation of a certain kernel module. This |
|---|
| 25 |
information is kept inside the kernel's Makefile tree, and stays in there. |
|---|
| 26 |
Until there is a better way of finding this out, we'll have to stick with |
|---|
| 27 |
another PITA in return for the initial one. |
|---|
| 28 |
|
|---|
| 29 |
The following shell function tries to find the kernel module name for a given |
|---|
| 30 |
kernel symbol: |
|---|
| 31 |
|
|---|
| 32 |
| func sym2kmod() { # ("<kernel symbol name>") |
|---|
| 33 |
| find . -name Makefile -print0 | \ |
|---|
| 34 |
| xargs -0 grep "obj-\$(CONFIG_$1).*\.o" | \ |
|---|
| 35 |
| sed -n 's/.*= \(.*\)\.o/\1/p' |
|---|
| 36 |
| } |
|---|
| 37 |
|
|---|
| 38 |
Trying to prove it's correctness: |
|---|
| 39 |
|
|---|
| 40 |
| grep FWRT_KPACKAGE_KMOD_ Config.in.kernelopts | \ |
|---|
| 41 |
| sed s/FWRT_KPACKAGE_KMOD_// > temp_kernel_module_symbols |
|---|
| 42 |
| for i in $(<temp_kernel_module_symbols); do |
|---|
| 43 |
| echo -n "$i: " |
|---|
| 44 |
| sym2kmod $i |
|---|
| 45 |
| done | grep -v : |
|---|
| 46 |
|
|---|
| 47 |
The output shows "fails". Interesting problems are: |
|---|
| 48 |
|
|---|
| 49 |
| sym2kmod IPX |
|---|
| 50 |
| sym2kmod ATALK |
|---|
| 51 |
| sym2kmod OPROFILE |
|---|
| 52 |
|
|---|
| 53 |
Doing a reverse lookup seems to be more successful. The following code |
|---|
| 54 |
searches the kernel path at $CWD for the corresponding symbol name to a given |
|---|
| 55 |
module name: |
|---|
| 56 |
|
|---|
| 57 |
| kmod2ksym() { # ("module basename") |
|---|
| 58 |
| find . -name Makefile -print0 | \ |
|---|
| 59 |
| xargs -0 grep "obj-\$(CONFIG_.*).*=.* $1.o" | \ |
|---|
| 60 |
| sed -n 's/.*obj-\$(CONFIG_\(.*\)).*=.*/\1/p' | \ |
|---|
| 61 |
| tr '\n' ' ' |
|---|
| 62 |
| echo "" |
|---|
| 63 |
| } |
|---|
| 64 |
|
|---|
| 65 |
The function prints a list of kernel symbols triggering the creation of the |
|---|
| 66 |
given module. If one of them is set to "y" via the ADK's menuconfig, the |
|---|
| 67 |
module has to be shipped within the rootfs image. |
|---|
| 68 |
|
|---|
| 69 |
The following function is a sample implementation of how the information |
|---|
| 70 |
gathered above could be formatted into a syntax understood by make: |
|---|
| 71 |
|
|---|
| 72 |
| kmoddeps() { # ("module basename") |
|---|
| 73 |
| for sym in `kmod2ksym $1`; do |
|---|
| 74 |
| printf 'obj-$(FWRT_KPACKAGE_KMOD_%s) += %s.ko\n' $sym $1 |
|---|
| 75 |
| done |
|---|
| 76 |
| } |
|---|
| 77 |
|
|---|
| 78 |
The Kmod_template in mk/kernel.mk adds the given kernel ipkg name to the make |
|---|
| 79 |
variable INSTALL_TARGETS. The install target in mk/kernel-build.mk then |
|---|
| 80 |
installs the mentioned names into the rootfs. |
|---|
| 81 |
|
|---|