1

標準コマンドを使用して、サイズ 34 の構造体を含むカーネル モジュールをコンパイルしています。

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

sizeof(some_structure)34 ではなく 36 として表示されます。つまり、コンパイラが構造体をパディングしています。

このパディングを削除するにはどうすればよいですか?

実行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 
4

3 に答える 3

5

GCC を使用している場合は、構造体にpacked属性を使用してパディングを防ぐことができます:

struct foo
{
    void * bar;
}
__attribute__( ( packed ) );
于 2010-05-04T07:21:07.777 に答える
1

#pragma packが動作する可能性があります

于 2010-05-04T07:21:09.983 に答える
0

GCCが構造全体を32ビット境界に揃えるように強制しているので、そのサイズは4の倍数であると思われます。

次のことを想像してみてください。struct foo {

ボイド*バー; 他のいくつかのもの.....};

struct foo my_foo_array [10];

次に、sizeof(struct foo)が4の倍数でない場合。my_foo_array [0] .barのメモリアライメントは、my_foo_array[1].barとは異なります。プロセッサは、my_foo_array [1] .barの4バイトすべてにアクセスするために、232ビットのメモリアクセスを実行する必要があります。x86プロセッサは、この位置ずれした32ビット値の再アセンブリを実行しますが、他のほとんどのプロセッサは、適切ではない何らかの形式のバスエラー例外をスローします。

packed属性は、構造体の要素が相互にどのようにパックされているかを示しますが、通常の操作では、構造体の開始を32ビットで整列されたアドレスに配置する必要があります。

これが物事をもう少しよく説明することを願っています。

于 2010-05-14T18:12:20.487 に答える