模块生成过程
文章目录
先看图:
模块编译过程
首先看一下普通外部模块编译的过程,这里用ldd3
的某些驱动来演示,执行下面命令:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- M=/home/mj/work/ldd3-master/misc-modules modules O=./out V=1
过程显示如下:
make -C /home/mj/work/linux-4.0/out KBUILD_SRC=/home/mj/work/linux-4.0 \
-f /home/mj/work/linux-4.0/Makefile modules
make[1]: Entering directory '/home/mj/work/linux-4.0/out'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p /home/mj/work/ldd3-master/misc-modules/.tmp_versions ; rm -f /home/mj/work/ldd3-master/misc-modules/.tmp_versions/*
make -f ../scripts/Makefile.build obj=/home/mj/work/ldd3-master/misc-modules
arm-linux-gnueabi-gcc -Wp,-MD,/home/mj/work/ldd3-master/misc-modules/.hello.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I/home/mj/work/ldd3-master/misc-modules -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(hello)" -D"KBUILD_MODNAME=KBUILD_STR(hello)" -c -o /home/mj/work/ldd3-master/misc-modules/hello.o /home/mj/work/ldd3-master/misc-modules/hello.c
arm-linux-gnueabi-gcc -Wp,-MD,/home/mj/work/ldd3-master/misc-modules/.hellop.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I/home/mj/work/ldd3-master/misc-modules -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(hellop)" -D"KBUILD_MODNAME=KBUILD_STR(hellop)" -c -o /home/mj/work/ldd3-master/misc-modules/hellop.o /home/mj/work/ldd3-master/misc-modules/hellop.c
(cat /dev/null; echo kernel//home/mj/work/ldd3-master/misc-modules/hello.ko; echo kernel//home/mj/work/ldd3-master/misc-modules/hellop.ko;) > /home/mj/work/ldd3-master/misc-modules/modules.order
make -f ../scripts/Makefile.modpost
find /home/mj/work/ldd3-master/misc-modules/.tmp_versions -name '*.mod' | xargs -r grep -h '\.ko$' | sort -u | sed 's/\.ko$/.o/' | scripts/mod/modpost -i ./Module.symvers -I /home/mj/work/ldd3-master/misc-modules/Module.symvers -o /home/mj/work/ldd3-master/misc-modules/Module.symvers -S -w -s -T -
arm-linux-gnueabi-gcc -Wp,-MD,/home/mj/work/ldd3-master/misc-modules/.hello.mod.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I/home/mj/work/ldd3-master/misc-modules -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(hello.mod)" -D"KBUILD_MODNAME=KBUILD_STR(hello)" -DMODULE -c -o /home/mj/work/ldd3-master/misc-modules/hello.mod.o /home/mj/work/ldd3-master/misc-modules/hello.mod.c
arm-linux-gnueabi-ld -EL -r -T ../scripts/module-common.lds --build-id -o /home/mj/work/ldd3-master/misc-modules/hello.ko /home/mj/work/ldd3-master/misc-modules/hello.o /home/mj/work/ldd3-master/misc-modules/hello.mod.o
arm-linux-gnueabi-gcc -Wp,-MD,/home/mj/work/ldd3-master/misc-modules/.hellop.mod.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I/home/mj/work/ldd3-master/misc-modules -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(hellop.mod)" -D"KBUILD_MODNAME=KBUILD_STR(hellop)" -DMODULE -c -o /home/mj/work/ldd3-master/misc-modules/hellop.mod.o /home/mj/work/ldd3-master/misc-modules/hellop.mod.c
arm-linux-gnueabi-ld -EL -r -T ../scripts/module-common.lds --build-id -o /home/mj/work/ldd3-master/misc-modules/hellop.ko /home/mj/work/ldd3-master/misc-modules/hellop.o /home/mj/work/ldd3-master/misc-modules/hellop.mod.o
make[1]: Leaving directory '/home/mj/work/linux-4.0/out'
配置内核的CONFIG_FUSE_FS=m
,编译成模块,执行下面命令:(指定M=./fs/fuse
在这个内核版本有问题)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- O=./out M=./fs modules V=1
过程如下:
make -C /home/mj/work/linux-4.0/out KBUILD_SRC=/home/mj/work/linux-4.0 \
-f /home/mj/work/linux-4.0/Makefile modules
make[1]: Entering directory '/home/mj/work/linux-4.0/out'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p ./fs/.tmp_versions ; rm -f ./fs/.tmp_versions/*
make -f ../scripts/Makefile.build obj=./fs
make -f ../scripts/Makefile.build obj=fs/9p
(cat /dev/null; ) > fs/9p/modules.order
make -f ../scripts/Makefile.build obj=fs/cramfs
(cat /dev/null; ) > fs/cramfs/modules.order
make -f ../scripts/Makefile.build obj=fs/debugfs
(cat /dev/null; ) > fs/debugfs/modules.order
make -f ../scripts/Makefile.build obj=fs/devpts
(cat /dev/null; ) > fs/devpts/modules.order
make -f ../scripts/Makefile.build obj=fs/exofs
(cat /dev/null; ) > fs/exofs/modules.order
make -f ../scripts/Makefile.build obj=fs/ext2
(cat /dev/null; ) > fs/ext2/modules.order
make -f ../scripts/Makefile.build obj=fs/ext3
(cat /dev/null; ) > fs/ext3/modules.order
make -f ../scripts/Makefile.build obj=fs/ext4
(cat /dev/null; ) > fs/ext4/modules.order
make -f ../scripts/Makefile.build obj=fs/fat
(cat /dev/null; ) > fs/fat/modules.order
make -f ../scripts/Makefile.build obj=fs/fuse
arm-linux-gnueabi-gcc -Wp,-MD,fs/fuse/.dev.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I../fs/fuse -Ifs/fuse -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(dev)" -D"KBUILD_MODNAME=KBUILD_STR(fuse)" -c -o fs/fuse/dev.o ../fs/fuse/dev.c
arm-linux-gnueabi-gcc -Wp,-MD,fs/fuse/.dir.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I../fs/fuse -Ifs/fuse -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(dir)" -D"KBUILD_MODNAME=KBUILD_STR(fuse)" -c -o fs/fuse/dir.o ../fs/fuse/dir.c
arm-linux-gnueabi-gcc -Wp,-MD,fs/fuse/.file.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I../fs/fuse -Ifs/fuse -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(file)" -D"KBUILD_MODNAME=KBUILD_STR(fuse)" -c -o fs/fuse/file.o ../fs/fuse/file.c
arm-linux-gnueabi-gcc -Wp,-MD,fs/fuse/.inode.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I../fs/fuse -Ifs/fuse -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(inode)" -D"KBUILD_MODNAME=KBUILD_STR(fuse)" -c -o fs/fuse/inode.o ../fs/fuse/inode.c
arm-linux-gnueabi-gcc -Wp,-MD,fs/fuse/.control.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I../fs/fuse -Ifs/fuse -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(control)" -D"KBUILD_MODNAME=KBUILD_STR(fuse)" -c -o fs/fuse/control.o ../fs/fuse/control.c
arm-linux-gnueabi-ld -EL -r -o fs/fuse/fuse.o fs/fuse/dev.o fs/fuse/dir.o fs/fuse/file.o fs/fuse/inode.o fs/fuse/control.o
(cat /dev/null; echo kernel/fs/fuse/fuse.ko;) > fs/fuse/modules.order
make -f ../scripts/Makefile.build obj=fs/jbd
(cat /dev/null; ) > fs/jbd/modules.order
make -f ../scripts/Makefile.build obj=fs/jbd2
(cat /dev/null; ) > fs/jbd2/modules.order
make -f ../scripts/Makefile.build obj=fs/jffs2
(cat /dev/null; ) > fs/jffs2/modules.order
make -f ../scripts/Makefile.build obj=fs/kernfs
(cat /dev/null; ) > fs/kernfs/modules.order
make -f ../scripts/Makefile.build obj=fs/lockd
(cat /dev/null; ) > fs/lockd/modules.order
make -f ../scripts/Makefile.build obj=fs/nfs
(cat /dev/null; ) > fs/nfs/modules.order
make -f ../scripts/Makefile.build obj=fs/nfs_common
(cat /dev/null; ) > fs/nfs_common/modules.order
make -f ../scripts/Makefile.build obj=fs/nls
(cat /dev/null; ) > fs/nls/modules.order
make -f ../scripts/Makefile.build obj=fs/notify
make -f ../scripts/Makefile.build obj=fs/notify/dnotify
(cat /dev/null; ) > fs/notify/dnotify/modules.order
make -f ../scripts/Makefile.build obj=fs/notify/fanotify
(cat /dev/null; ) > fs/notify/fanotify/modules.order
make -f ../scripts/Makefile.build obj=fs/notify/inotify
(cat /dev/null; ) > fs/notify/inotify/modules.order
(cat /dev/null; cat fs/notify/dnotify/modules.order; cat fs/notify/inotify/modules.order; cat fs/notify/fanotify/modules.order;) > fs/notify/modules.order
make -f ../scripts/Makefile.build obj=fs/proc
(cat /dev/null; ) > fs/proc/modules.order
make -f ../scripts/Makefile.build obj=fs/quota
(cat /dev/null; ) > fs/quota/modules.order
make -f ../scripts/Makefile.build obj=fs/ramfs
(cat /dev/null; ) > fs/ramfs/modules.order
make -f ../scripts/Makefile.build obj=fs/squashfs
(cat /dev/null; ) > fs/squashfs/modules.order
make -f ../scripts/Makefile.build obj=fs/sysfs
(cat /dev/null; ) > fs/sysfs/modules.order
make -f ../scripts/Makefile.build obj=fs/ubifs
(cat /dev/null; ) > fs/ubifs/modules.order
(cat /dev/null; cat ./fs/notify/modules.order; cat ./fs/nfs_common/modules.order; cat ./fs/quota/modules.order; cat ./fs/proc/modules.order; cat ./fs/kernfs/modules.order; cat ./fs/sysfs/modules.order; cat ./fs/devpts/modules.order; cat ./fs/ext3/modules.order; cat ./fs/ext2/modules.order; cat ./fs/ext4/modules.order; cat ./fs/jbd/modules.order; cat ./fs/jbd2/modules.order; cat ./fs/cramfs/modules.order; cat ./fs/squashfs/modules.order; cat ./fs/ramfs/modules.order; cat ./fs/fat/modules.order; cat ./fs/nfs/modules.order; cat ./fs/lockd/modules.order; cat ./fs/nls/modules.order; cat ./fs/jffs2/modules.order; cat ./fs/ubifs/modules.order; cat ./fs/9p/modules.order; cat ./fs/debugfs/modules.order; cat ./fs/exofs/modules.order; cat ./fs/fuse/modules.order;) > fs/modules.order
make -f ../scripts/Makefile.modpost
find ./fs/.tmp_versions -name '*.mod' | xargs -r grep -h '\.ko$' | sort -u | sed 's/\.ko$/.o/' | scripts/mod/modpost -i ./Module.symvers -I ./fs/Module.symvers -o ./fs/Module.symvers -S -w -s -T -
arm-linux-gnueabi-gcc -Wp,-MD,fs/fuse/.fuse.mod.o.d -nostdinc -isystem /usr/lib/gcc-cross/arm-linux-gnueabi/5/include -I../arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated -I../include -Iinclude -I../arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I../include/uapi -Iinclude/generated/uapi -include ../include/linux/kconfig.h -I.././fs -I./fs -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(fuse.mod)" -D"KBUILD_MODNAME=KBUILD_STR(fuse)" -DMODULE -c -o fs/fuse/fuse.mod.o fs/fuse/fuse.mod.c
arm-linux-gnueabi-ld -EL -r -T ../scripts/module-common.lds --build-id -o fs/fuse/fuse.ko fs/fuse/fuse.o fs/fuse/fuse.mod.o
make[1]: Leaving directory '/home/mj/work/linux-4.0/out'
对比这两个过程,可以发现实际上的过程并无太大差异,可以从下图看出:
那么问题来了,这个hello.mod.c
和fuse.mod.c
是从哪里来的?这就要说到scripts/mod/modpost
这个工具了。
modpost
直接看源码,首先是main()
函数里面对入参进行判断,获取内核的符号信息文件(linux内核顶层的Module.symvers),以及依赖的当前编译路径下的符号信息文件和要输出的符号信息文件(模块编译路径下的Module.symvers)。当然,一般情况下,模块里有EXPORT_SYMBOL*
才会有模块信息导出。然后还有一些警告选项的配置,就不多说了。接下来就是.mod.c
文件的生成过程了,看下面的函数就可以看到一些关键信息:__this_module
,__module_depends
等。最后导出符号信息,结束。
read_dump()/write_dump()
导入/导出符号信息
read_dump()
映射了Module.symvers
文件后,遍历文件的每一行,然后获取符号名称,所在的模块(或者是vmlinux
)以及符号的类型,最前面的crc
暂时就不管了。排布类型如下:
/* 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something] */
0x00000000 fsg_fs_function drivers/usb/gadget/function/usb_f_mass_storage EXPORT_SYMBOL_GPL
...
0x00000000 class_interface_unregister vmlinux EXPORT_SYMBOL_GPL
...
0x00000000 memmove vmlinux EXPORT_SYMBOL
..
读出符号和所在的模块信息后,对信息进行一个记录,模块就放到模块的记录链表中,符号放到记录符号的链表中。
模块的查找和申请也很简单,就是链表的操作:
导出模块符号时,需要注意到不能出现相同的符号,否则这里会给出警告:
在符号的记录与查找时,利用了hash数组去加快查找速度:
至于导出符号的类型,可以看export_list
:
至于write_dump()
,遍历hash数组判断是否需要导出相关符号即可。
对于正常构建,始终转储所有符号。
对于外部模块,仅转储未从内核模块中读取的符号。
read_symbols()
从ELF文件中读取符号并记录
read_symbols_from_files()
从-T
选项输入的.o
文件中读取相关的符号信息,而主要是这个 read_symbols()
函数。
read_symbols()
就是对ELF
文件校验后,读出里面的符号表信息,并记录在当前运行的环境中。
parse_elf()
解析elf
文件,主要是校验ELF
头,读取各个section
的位置后,找到与模块信息相关的sectnon
,比如.modinfo
模块信息,__ksymtab
导出符号等,最主要的其实是符号表SHT_SYMTAB
,这里面记录的就是函数名、变量名等字符串信息。将符号表的起始地址和结束地址记录,方便后续使用。
get_modinfo()
是从前面parse_elf()
记录的.modinfo
里面获取相关的信息,比如里面的license
,version
。
比如这样:license=GPL
。
handle_modversions()
主要就是把未定义的符号和要导出的符号先记录下来。
check_exports()
检查符号与GPL协议匹配情况
check_exports()
检查模块所用到的符号是否与GPL协议相悖。
检查协议的如下:
导出的符号的过程在上面的export_from_secname()
或export_from_sec()
,在handle_modversions()
时:
生成.mod.c文件
输出头文件信息、.gnu.linkonce.this_module
节,以及init
,exit
等相关信息。
add_versions()
增加modversion_info
,警告为定义符号等。
其实到.mod.c
生成了,整个模块到生成模块基本就完成了。剩下的就是把.mod.c
生成的.mod.o
和原来的.o
文件进行一个链接。
module-common.lds
这个直接看就好了,对各种___ksymtab
,___ksymtab_gpl
等符号进行排序,init_array
进行ALIGN(8)
对齐。
好了,模块生成就暂时这样把。