これは何?
Ubuntu18.04でPEX-361316を利用したい。
いくつかモジュールを組み込む必要があるが、カーネルが新しいため、ビルドが必要。ビルドを通す際の記録。
いくつかビルドを通す必要があるが、長くなるため、gpg3100のみを取り上げます。
ビルドを通すまで
$ cd ~/work/PEX-361316/gpg3100/x86_64/linux/drivers/src
Makefileを編集。
CFLAGS += -I$(INCLUDEDIR)
CFLAGS += -fno-pie // 追加
ad_entry.cを編集。
ad_entry.c
# include <linux/kconfig.h> // 追加
# include <linux/kernel.h>
//return(MINOR(((struct file *)file)->f_dentry->d_inode->i_rdev));
return(MINOR(((struct file *)file)->f_path.dentry->d_inode->i_rdev));
/*
ret = get_user_pages(
current,
current->mm,
(Buffer & PAGE_MASK),
mdl->NumberOfPages,
Direction,
1,
(struct page **)mdl->PageList,
NULL);
*/
if(Direction == WRITE) {
ret = get_user_pages((Buffer & PAGE_MASK), mdl->NumberOfPages,
FOLL_FORCE | FOLL_WRITE, (struct page **)mdl->PageList, NULL);
} else {
ret = get_user_pages((Buffer & PAGE_MASK), mdl->NumberOfPages,
FOLL_FORCE, (struct page **)mdl->PageList, NULL);
}
//page_cache_release((struct page *)mdl->PageList[i]);
put_page((struct page *)mdl->PageList[i]);
// もう1箇所同様に修正
void gpg_ad_add_timer(void *ext, void *function, unsigned long data, unsigned long expires)
{
PAD_EXTERNAL_STRUCT pExt;
pExt = (PAD_EXTERNAL_STRUCT)ext;
/*
pExt->ad_timer.function = function;
pExt->ad_timer.data = data;
*/
timer_setup(&(pExt->ad_timer), function, data); // 追加
pExt->ad_timer.expires = expires;
add_timer(&(pExt->ad_timer));
}
makeするとcp3100.mod.cが生成され、ビルドエラーで止まる。
cp3100.mod.c
# include <linux/kconfig.h> // 追加
# include <linux/build-salt.h>
ビルドが通る。
$ make
...
ld -m elf_x86_64 -r -o cp3100.ko cp3100.o cp3100.mod.o
$ sudo make install
...
mkdir -p /lib/modules/5.0.0-37-generic/misc
cp -f cp3100.ko /lib/modules/5.0.0-37-generic/misc
$
カーネル 5.0.37 から 5.3.26 への対応
カーネルの変化でビルドの通し方がちょっと変わった。
以下以外は5.0.37と同じです。
ad_entry.c
# include <linux/kconfig.h>
typedef long long __kernel_time64_t; // 追加
cp3100.mod.c
# include <linux/kconfig.h> // 追加( 5.0.37の時も )
typedef long long __kernel_time64_t; // 追加
ロード
$ sudo depmod -a
$ sudo modprobe cp3100
modprobe: ERROR: could not insert 'cp3100': Unknown symbol in module, or unknown parameter (see dmesg)
$ dmesg
...
[ 1026.613494] cp3100: Unknown symbol gpg_outl (err -2)
[ 1026.613506] cp3100: Unknown symbol gpg_iounmap (err -2)
[ 1026.613517] cp3100: Unknown symbol gpg_vfree (err -2)
[ 1026.613528] cp3100: Unknown symbol gpg_copy_from_user (err -2)
[ 1026.613539] cp3100: Unknown symbol gpg_udelay (err -2)
[ 1026.613551] cp3100: Unknown symbol gpg_writew (err -2)
[ 1026.613562] cp3100: Unknown symbol gpg_writel (err -2)
[ 1026.613573] cp3100: Unknown symbol gpg_interruptible_sleep_on (err -2)
[ 1026.613584] cp3100: Unknown symbol gpg_readw (err -2)
[ 1026.613598] cp3100: Unknown symbol signal_pending (err -2)
[ 1026.613609] cp3100: Unknown symbol gpg_get_file_f_version (err -2)
[ 1026.613620] cp3100: Unknown symbol interruptible_sleep_on_timeout (err -2)
[ 1026.613631] cp3100: Unknown symbol gpg_free_irq (err -2)
[ 1026.613644] cp3100: Unknown symbol gpg_inw (err -2)
[ 1026.613657] cp3100: Unknown symbol init_timer (err -2)
[ 1026.613668] cp3100: Unknown symbol gpg_release_region (err -2)
[ 1026.613679] cp3100: Unknown symbol gpg_request_mem_region (err -2)
[ 1026.613690] cp3100: Unknown symbol gpg_read_pcidevice_data (err -2)
[ 1026.613701] cp3100: Unknown symbol gpg_outb (err -2)
[ 1026.613713] cp3100: Unknown symbol gpg_writeb (err -2)
[ 1026.613724] cp3100: Unknown symbol gpg_MINOR (err -2)
[ 1026.613737] cp3100: Unknown symbol gpg_request_region (err -2)
[ 1026.613748] cp3100: Unknown symbol gpg_pci_find_subsys (err -2)
[ 1026.613759] cp3100: Unknown symbol gpg_pci_find_device (err -2)
[ 1026.613770] cp3100: Unknown symbol gpg_set_file_private_data (err -2)
[ 1026.613781] cp3100: Unknown symbol gpg_insw (err -2)
[ 1026.613792] cp3100: Unknown symbol gpg_inb (err -2)
[ 1026.613804] cp3100: Unknown symbol gpg_ioremap (err -2)
[ 1026.613816] cp3100: Unknown symbol gpg_memcpy (err -2)
[ 1026.613827] cp3100: Unknown symbol gpg_version_disp_load (err -2)
[ 1026.613838] cp3100: Unknown symbol gpg_pci_set_master (err -2)
[ 1026.613850] cp3100: Unknown symbol gpg_copy_to_user (err -2)
[ 1026.613861] cp3100: Unknown symbol gpg_vmalloc (err -2)
[ 1026.613874] cp3100: Unknown symbol gpg_version_disp_unload (err -2)
[ 1026.613886] cp3100: Unknown symbol gpg_inl (err -2)
[ 1026.613897] cp3100: Unknown symbol gpg_readb (err -2)
[ 1026.613907] cp3100: Unknown symbol gpg_outw (err -2)
[ 1026.613919] cp3100: Unknown symbol gpg_printk (err -2)
[ 1026.613930] cp3100: Unknown symbol gpg_readl (err -2)
[ 1026.613941] cp3100: Unknown symbol gpg_memset (err -2)
失敗する。gpg_XXXはdpg0100のビルドの問題。
ほかは、以下で対応。
ad_entry.c
...
# include <linux/sched/signal.h> // 追加( signal_pending の対応 )
...
/* interruptible_sleep_on_timeoutの対応。dpg0100.cを参照し、gpg_interruptible_sleep_on_timeoutを */
/* 呼び出せば、同じことがやれると判断。 */
/* 以下のように interruptible_sleep_on_timeout を gpg_interruptible_sleep_on_timeout に名称変更(4箇所) */
case SMPL:
lret = gpg_interruptible_sleep_on_timeout(&(pExt->smpl_wait), timeout);
break;
...
/* コールバック関数追加。タイマーが切れたときに呼ばれる。 */
static void gpg_timer_fn(struct timer_list *t)
{
return;
}
void gpg_ad_init_timer(void *ext)
{
PAD_EXTERNAL_STRUCT pExt;
pExt = (PAD_EXTERNAL_STRUCT)ext;
//init_timer(&(pExt->ad_timer));
timer_setup((struct timer_list *)(&(pExt->ad_timer)), gpg_timer_fn, 0); // 追加
}
...
Makefile
CFILES = ad_entry.c
obj-m += cp3100.o
cp3100-objs := $(CFILES:.c=.o) ../ver26/bocp3100noreg.o
VERBOSE = 0
KBUILD_EXTRA_SYMBOLS = .../PEX-361316/common/dpg0100/src/Module.symvers
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) KBUILD_VERBOSE=$(VERBOSE) CONFIG_DEBUG_INFO=y modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
install:
cp -f cp3100.ko /lib/modules/$(shell uname -r)/misc
$ ln ../../../../../common/dpg0100/src/dpg0100.h .
$ make
$ sudo make install
$ sudo depmod -a
$ sudo modprobe cp3100
$ dmesg
...
[13190.651470] pci 0000:05:0c.0: enabling device (0000 -> 0002)
[13190.651627] cp3100:Interface Analog Input Device Driver (Ver5.01.38.00) loaded.
参考ページ
- linuxカーネル内部インターフェースの変更例 - Qiita
-
struct timer_list ad_timerの変更について - Ubuntu18.04でdpg0100のビルド - Qiita
- ソースファイルの分割 | Linuxデバイスドライバ開発入門
- Linux source code: signal_pending identifier (v5.0.21) - Bootlin
- ART-Linux on Ubuntu 10.04
-
interruptible_sleep_on_timeoutの参考 - c++ - linux kernel module linker warnings: "*** Warning: <function> [<module>] undefined!" - any way to get rid of them? - Stack Overflow