rpmbuild打包错误——needs unknown symbol *

环境:CentOS8,使用redhat的spec文件编译4.19内核。

命令:rpmbuild -bb 4.19.0.src.rpm

解决方法:

1.查找没找到的符号所在模块,查看是否在.config文件中打开。

2.在rpmbuild/SOURCES/filter-modules.sh文件中有一个过滤名单,将出错的模块名添加到名单中,这样导出符号时会忽略这个模块,也不影响功能。要注意的是,在rpmbuild/SOURCES/目录下有好几个filter-*.sh文件,分别对应不同的架构,也需要修改。不然编译对应架构的包也会同样的错。

下面是较为详细的分析过程:

错误日志(部分,已模糊处理):

+ cat depmod.out
Depmod failure
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_new
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_limit_hw_rates
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_card_register
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_card_free
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_lib_preallocate_pages_for_all
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_hw_constraint_minmax
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_set_sync
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_card_new
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_lib_malloc_pages
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_lib_ioctl
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_lib_free_pages
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_card_free_when_closed
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_set_ops
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_suspend_all
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_card_disconnect
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_hw_constraint_integer
depmod: WARNING: /builddir/build/BUILDROOT/kernel-4.19.0/./lib/modules/kernel-4.19.0/kernel/drivers/gpu/drm/test/test.ko needs unknown symbol snd_pcm_period_elapsed
RPM build errors:

上面的错误是“needs unknown symbol *”,这个表示没有找到实现的函数,说明该函数对应的文件没有被编译或者加入内核代码中,通过以下几步确认相关问题(以上面的错误为例):

1.在内核代码目录使用“grep -rn snd_pcm_new”查找此函数的实现位置,在输出结果中可以找到这样一行:

sound/core/pcm.c:837:int snd_pcm_new(struct snd_card *card, const char *id, int device,

说明这个函数实现在sound/core/pcm.c文件。

2.接下来查看此文件是否被编译,结合sound/core目录的Makefile,查看是否存在对应的“.o”或“.ko”文件,有则说明已经被编译,理论上编译器已经找到了该文件。没有说明内核编译使用的config不对,里面对应的CONFIG_*项没有打开。

查看sound/core/Makefile,发现其生成文件对应的配置为CONFIG_SND_PCM,然后尝试打开就行了。

snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_misc.o \
		pcm_memory.o memalloc.o

(对应的Makefile部分,注意,snd-pcm-y即表示CONFIG_SND_PCM被打开,pcm.o是pcm.c对应的工程文件。字符名称有对应关系,感谢内核开发者。当然既可能是=y,也可能=m,取决于代码要不要被编进内核。)

打开.config,发现CONFIG_SND_PCM已经打开,因此说明内核已经有这个模块了。那就有可能是打包过程中的问题。

3.在rpmbuild/BUILDROOT/lib/modules/kernel/sound/core目录下面,发现没有任何ko文件,然后整个sound目录都没有ko文件,说明这个目录底下的模块都被删除了,这很有可能就是原因。

在rpmbuild/BUILDROOT/目录下有两个文件夹,lib和restore,restore由lib/modules/kernel复制得到,可以在restore下面找到sound目录的ko文件,而lib/modules/kernel没有,说明复制到restore之后,做了一些处理,删除了一些文件。

先尝试在rpmbuild/SOURCES/文件夹里找一下可能对kernel/sound目录操作的脚本,使用“grep -rn "kernel/sound"”。果然找到了一个脚本文件“filter-modules.sh”,看了一下内容,这个脚本负责删除一些指定模块,生成一个精简的内核便于导出内核符号,因此问题可能出在这里。找到对应“kernel/sound”的一行,如下:

# Just kill sound.
filter_dir $1 kernel/sound

注释说明这里确实删除了sound里的东西,分析其他部分的代码可知,这里的作用就是删除指定目录的模块,预设的数组如下:

driverdirs="atm auxdisplay bcma bluetooth firewire fmc iio infiniband isdn leds media memstick mfd mmc mtd nfc ntb pcmcia platform power ssb staging tty uio uwb w1"

chardrvs="mwave pcmcia"

netdrvs="appletalk can dsa hamradio ieee802154 irda ppp slip usb wireless"

ethdrvs="3com adaptec alteon amd aquantia atheros broadcom cadence calxeda chelsio cisco dec dlink emulex icplus marvell neterion nvidia oki-semi packetengines qlogic rdc renesas sfc silan sis smsc stmicro sun tehuti ti wiznet xircom"

inputdrvs="gameport tablet touchscreen"

scsidrvs="aacraid aic7xxx aic94xx be2iscsi bfa bnx2i bnx2fc csiostor cxgbi esas2r fcoe fnic hisi_sas isci libsas lpfc megaraid mpt2sas mpt3sas mvsas pm8001 qla2xxx qla4xxx sym53c8xx_2 ufs qedf"

usbdrvs="atm image misc serial wusbcore"

fsdrvs="affs befs coda cramfs ecryptfs hfs hfsplus jfs minix ncpfs nilfs2 ocfs2 reiserfs romfs squashfs sysv ubifs ufs"

netprots="6lowpan appletalk atm ax25 batman-adv bluetooth can dccp dsa ieee802154 irda l2tp mac80211 mac802154 mpls netrom nfc rds rfkill rose sctp smc wireless"

drmdrvs="amd ast gma500 i2c i915 mgag200 nouveau radeon via"

singlemods="ntb_netdev iscsi_ibft iscsi_boot_sysfs megaraid pmcraid qedi qla1280 9pnet_rdma rpcrdma nvmet-rdma nvme-rdma hid-picolcd hid-prodikeys hwa-hc hwpoison-inject hid-sensor-hub target_core_user sbp_target cxgbit iw_cxgb3 iw_cxgb4 cxgb3i cxgb3i cxgb3i_ddp cxgb4i chcr parport_serial ism"

对应的过滤脚本如下:

# Filter the drivers/ subsystems
for subsys in ${driverdirs}
do
        filter_dir $1 drivers/${subsys}
done

# Filter the networking drivers
for netdrv in ${netdrvs}
do
        filter_dir $1 drivers/net/${netdrv}
done

# Filter the char drivers
for char in ${chardrvs}
do
        filter_dir $1 drivers/char/${input}
done

# Filter the ethernet drivers
for eth in ${ethdrvs}
do
        filter_dir $1 drivers/net/ethernet/${eth}
done

# SCSI
for scsi in ${scsidrvs}
do
        filter_dir $1 drivers/scsi/${scsi}
done

# Input
for input in ${inputdrvs}
do
        filter_dir $1 drivers/input/${input}
done

# USB
for usb in ${usbdrvs}
do
        filter_dir $1 drivers/usb/${usb}
done

# Filesystems
for fs in ${fsdrvs}
do
        filter_dir $1 fs/${fs}
done

# Network protocols
for prot in ${netprots}
do
        filter_dir $1 kernel/net/${prot}
done

# DRM
for drm in ${drmdrvs}
do
        filter_dir $1 drivers/gpu/drm/${drm}
done

# Just kill sound.
filter_dir $1 kernel/sound

所以只要将报错的模块添加到对应的数组中,不用导出这个模块的符号,就可以避免这个问题。当然,也可以把缺少的部分模块从这些数组中去除,但是本例中需要去除的模块比较多,因此采用第一种方法。将test添加到数组drmdrvs中,因为都在同一个目录底下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值