1

I am trying to write a module for an sbc1651. Since the device is ARM, this requires a cross-compile. As a start, I am trying to compile the "Hello Kernel" module found here. This compiles fine on my x86 development system, but when I try to cross-compile I get the below warning.

/home/developer/HelloKernel/hello-1.mod.c:14: warning: missing initializer
/home/developer/HelloKernel/hello-1.mod.c:14: warning: (near initialization for '__this_module.arch.unw_sec_init')   

Since this is in the .mod.c file, which is autogenerated I have no idea what's going on. The mod.c file seems to be generated by the module.h file. As far as I can tell, the relevant parts are the same between my x86 system's module.h and the arm kernel header's module.h.

Adding to my confusion, this problem is either not googleable (by me...) or hasn't happened to anyone before. Or I'm just doing something clueless that anyone with any sense wouldn't do.

The cross-compiler I'm using was supplied by Freescale (I think). I suppose it could be a problem with the compiler. Would it be worth trying to build the toolchain myself? Obviously, since this is a warning, I could ignore it, but since it's so strange, I am worried about it, and would like to at least know the cause...

Thanks very much,
Sompom

Here are the source files
hello-1.mod.c

#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>

MODULE_INFO(vermagic, VERMAGIC_STRING);

struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
 .name = KBUILD_MODNAME,
 .init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
 .exit = cleanup_module,
#endif
 .arch = MODULE_ARCH_INIT,
};

static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
    { 0x3972220f, "module_layout" },
    { 0xefd6cf06, "__aeabi_unwind_cpp_pr0" },
    { 0xea147363, "printk" },
};

static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";

hello-1.c (modified slightly from the given link)

/*  hello-1.c - The simplest kernel module.
 *
 *  Copyright (C) 2001 by Peter Jay Salzman
 *
 *  08/02/2006 - Updated by Rodrigo Rubira Branco <rodrigo@kernelhacking.com>
 */

/* Kernel Programming */
#ifndef MODULE
    #define MODULE
#endif
#ifndef LINUX
    #define LINUX
#endif
#ifndef __KERNEL__
    #define __KERNEL__
#endif

#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>  /* Needed for KERN_ALERT */


static int hello_init_module(void)
{
   printk(KERN_ALERT "Hello world 1.\n");

   /* A non 0 return means init_module failed; module can't be loaded.*/
   return 0;
}


static void hello_cleanup_module(void)
{
  printk(KERN_ALERT "Goodbye world 1.\n");
}  

module_init(hello_init_module);
module_exit(hello_cleanup_module);

MODULE_LICENSE("GPL");

Makefile

export ARCH:=arm
export CCPREFIX:=/opt/freescale/usr/local/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/arm-linux-
export CROSS_COMPILE:=${CCPREFIX}

TARGET  := hello-1
WARN    := -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wno-sign-compare -Wno-unused -Werror
UNUSED_FLAGS :=  -std=c99 -pedantic 
EXTRA_CFLAGS  := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE}
KDIR ?= /home/developer/src/ltib-microsys/ltib/rpm/BUILD/linux-2.6.35.3

ifneq ($(KERNELRELEASE),)
# kbuild part of makefile
obj-m  := $(TARGET).o

else
# normal makefile

default: clean
    $(MAKE) -C $(KDIR) M=$$PWD

.PHONY: clean
clean:
    -rm built-in.o
    -rm $(TARGET).ko
    -rm $(TARGET).ko.unsigned
    -rm $(TARGET).mod.c
    -rm $(TARGET).mod.o
    -rm $(TARGET).o
    -rm modules.order
    -rm Module.symvers

endif
Deepend
  • 4,057
  • 17
  • 60
  • 101
Sompom
  • 223
  • 2
  • 13
  • Hi there, welcome to SO. Could you please edit your question to clarify which errors you are getting and when? The error in the title is a warning you see when you compile locally? but the error in the question is when you cross compile? – Deepend Jun 09 '14 at 18:35
  • Hi @Deepend, The error is the same, just that I compressed the error in the title onto one line to make it less unwieldy. Thanks, Sompom – Sompom Jun 09 '14 at 19:06
  • Looks like the macro MODULE_ARCH_INIT is undefined when the the preprocessor gets to line 14. Maybe it was in the regular compiler makefile but not the cross-compiler makefile? – Austin Mullins Jun 09 '14 at 19:38
  • Hmm. I copied the same Makefile, only adding the top three "export" lines to make it cross-compile. The reference I have to that macro is http://lxr.free-electrons.com/source/include/linux/module.h?v=2.6.34#L383 . The cross-compiling kernel headers have the same reference in the same place. The line doesn't make any sense to me, since if it's defining it as {}, it would do nothing. But I suppose that's what I'm seeing. – Sompom Jun 09 '14 at 19:47
  • @Deepend Your last edit suggestion was incorrect, I think: the OP was correct in classifying this as a warning rather than an error, and already explained that it happened when cross-compiling. –  Jun 09 '14 at 21:25
  • @hvd Changed that to warning. I moved the reference to cross-compile from below the warning to above to improve the flow of English. – Deepend Jun 09 '14 at 21:32
  • @Deepend Thanks. Personally I think that was minor enough that it could be left as is, but if you did think it was unclear as it was, you were right to suggest to change it. –  Jun 09 '14 at 21:35
  • First, that statement that a warning can be ignored is (almost) always false. Warnings should/must always be fixed. – user3629249 Jun 09 '14 at 23:40

1 Answers1

1

Apparently MODULE_ARCH_INIT is a macro defined as some sort of { ... } initializer. GCC is known for issuing overly paranoid (and downright malicious) warnings for such initializers when they don't cover every field in the target aggregate, even though the language spec says that everything is OK.

Here is an example of that warning issued for the perfectly safe (and idiomatic) = { 0 } initializer: Why is the compiler throwing this warning: "missing initializer"? Isn't the structure initialized?

I'd guess that your MODULE_ARCH_INIT is defined as something that does not cover every field of the target struct and triggers the very same warning for the very same reason.

The language guarantees that in such cases non-covered fields are zero-initialized, but GCC is just not sure whether zero is what you want to initialize those fields with. Hence the warning.

Community
  • 1
  • 1
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765