从内核模块中的结构中删除填充

时间:2010-05-04 07:15:36

标签: gcc makefile linux-kernel kernel-module packing

我正在使用标准命令编译包含34号结构的内核模块。

make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules

sizeof(some_structure)为36而不是34,即编译器正在填充结构。

如何删除此填充?

运行make V=1显示作为

传递的gcc编译器选项
make -I../inc -C /lib/modules/2.6.29.4-167.fc11.i686.PAE/build M=/home/vishal/20100426_eth_vishal/organised_eth/src modules

make[1]: Entering directory `/usr/src/kernels/2.6.29.4-167.fc11.i686.PAE'
test -e include/linux/autoconf.h -a -e include/config/auto.conf || (  \
 echo;        \
 echo "  ERROR: Kernel configuration is invalid.";  \
 echo "         include/linux/autoconf.h or include/config/auto.conf are missing."; \
 echo "         Run 'make oldconfig && make prepare' on kernel src to fix it."; \
 echo;        \
 /bin/false)

mkdir -p /home/vishal/20100426_eth_vishal/organised_eth/src/.tmp_versions ; rm -f /home/vishal/20100426_eth_vishal/organised_eth/src/.tmp_versions/*

make -f scripts/Makefile.build obj=/home/vishal/20100426_eth_vishal/organised_eth/src

  gcc -Wp,-MD,/home/vishal/20100426_eth_vishal/organised_eth/src/.eth_main.o.d  -nostdinc -isystem /usr/lib/gcc/i586-redhat-linux/4.4.0/include -Iinclude  -I/usr/src/kernels/2.6.29.4-167.fc11.i686.PAE/arch/x86/include -include include/linux/autoconf.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -Wa,-mtune=generic32 -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iarch/x86/include/asm/mach-generic -Iarch/x86/include/asm/mach-default -Wframe-larger-than=1024 -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pg -Wdeclaration-after-statement -Wno-pointer-sign -fwrapv -fno-dwarf2-cfi-asm -DTX_DESCRIPTOR_IN_SYSTEM_MEMORY -DRX_DESCRIPTOR_IN_SYSTEM_MEMORY -DTX_BUFFER_IN_SYSTEM_MEMORY -DRX_BUFFER_IN_SYSTEM_MEMORY -DALTERNATE_DESCRIPTORS -DEXT_8_BYTE_DESCRIPTOR -O0 -Wall -DT_ETH_1588_051 -DALTERNATE_DESCRIPTORS -DEXT_8_BYTE_DESCRIPTOR -DNETHERNET_INTERRUPTS -DETH_IEEE1588_TESTS -DSNAPTYPSEL_TMSTRENA_TEVENTENA_TESTS -DT_ETH_1588_140_147 -DLOW_DEBUG_PRINTS -DMEDIUM_DEBUG_PRINTS -DHIGH_DEBUG_PRINTS -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(eth_main)"  -D"KBUILD_MODNAME=KBUILD_STR(conxt_eth)"  -c -o /home/vishal/20100426_eth_vishal/organised_eth/src/eth_main.o /home/vishal/20100426_eth_vishal/organised_eth/src/eth_main.c 

3 个答案:

答案 0 :(得分:4)

如果使用GCC,您可以使用结构上的压缩属性来防止填充:

struct foo
{
    void * bar;
}
__attribute__( ( packed ) );

答案 1 :(得分:1)

#pragma pack可能有效

答案 2 :(得分:0)

我怀疑GCC强制将整个结构对齐到32位边界,因此它的大小是4的倍数。

想象一下以下内容。 struct foo {

void * bar;  一些其他的东西..... };

struct foo my_foo_array [10];

然后,如果sizeof(struct foo)不是4的倍数那么。 my_foo_array [0] .bar与my_foo_array [1] .bar有不同的内存对齐方式。处理器需要执行2次32位内存访问才能访问my_foo_array [1] .bar的所有四个字节。 x86处理器将重新组装未对齐的32位值,但大多数其他处理器将抛出某种形式的总线错误异常,这是不好的。

packed属性表示结构元素如何相互打包,但在正常操作中,结构的开始需要放在32位对齐的地址上。

我希望这能更好地解释事情。