3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ubuntu18.04でdpg0100のビルド

Last updated at Posted at 2020-01-11

これは何?

Ubuntu18.04でPEX-361316を利用したい。
いくつかモジュールを組み込む必要があるが、カーネルが新しいため、ビルドが必要。ビルドを通す際の記録。
いくつかビルドを通す必要があるが、長くなるため、dpg0100のみを取り上げます。

ビルドを通すまで

とりあえずmake

$ cd ~/work/PEX-361316/common/dpg0100/src
$ make
cc1: fatal error: /lib/modules/5.0.0-37-generic/build/include/linux/version.h: そのようなファイルやディレクトリはありません
compilation terminated.
gcc -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -Wall -Wstrict-prototypes -O -fomit-frame-pointer -pipe -ffreestanding -fno-strict-aliasing -fno-common -I/lib/modules/5.0.0-37-generic/build/include -I/lib/modules/5.0.0-37-generic/build/arch/x86/include -I/lib/modules/5.0.0-37-generic/build/include/asm/mach-default -I/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/mach-generic  -mcmodel=kernel -mno-red-zone -include /lib/modules/5.0.0-37-generic/build/include/generated/autoconf.h -D__SMP__ -DEXPORT_SYMTAB -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(dpg0100)" -D"KBUILD_MODNAME=KBUILD_STR(dpg0100)"   -c -o dpg0100.o dpg0100.c
cc1: error: code model kernel does not support PIC mode
<ビルトイン>: recipe for target 'dpg0100.o' failed
make: *** [dpg0100.o] Error 1

version.hが無いため、生成する。

$ sudo apt install linux-headers-`uname -r`
$ cd /usr/src/linux-headers-5.0.0-37/
$ sudo make include/generated/uapi/linux/version.h
$ sudo ln -s /usr/src/linux-headers-5.0.0-37/include/generated/uapi/linux/version.h /lib/modules/5.0.0-37-generic/build/include/linux/version.h
$ cd ~/work/PEX-361316/common/dpg0100/src
$ make
gcc -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -Wall -Wstrict-prototypes -O -fomit-frame-pointer -pipe -ffreestanding -fno-strict-aliasing -fno-common -I/lib/modules/5.0.0-37-generic/build/include -I/lib/modules/5.0.0-37-generic/build/arch/x86/include -I/lib/modules/5.0.0-37-generic/build/include/asm/mach-default -I/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/mach-generic  -mcmodel=kernel -mno-red-zone -include /lib/modules/5.0.0-37-generic/build/include/generated/autoconf.h -D__SMP__ -DEXPORT_SYMTAB -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(dpg0100)" -D"KBUILD_MODNAME=KBUILD_STR(dpg0100)"   -c -o dpg0100.o dpg0100.c
cc1: error: code model kernel does not support PIC mode
<ビルトイン>: recipe for target 'dpg0100.o' failed
make: *** [dpg0100.o] Error 1

以下を/lib/modules/5.0.0-37-generic/build/Makefile内のall: vmlinuxの下に追加。

# force no-pie for distro compilers that enable pie by default
KBUILD_CFLAGS += $(call cc-option, -fno-pie) 
KBUILD_CFLAGS += $(call cc-option, -no-pie)
KBUILD_AFLAGS += $(call cc-option, -fno-pie)
KBUILD_CPPFLAGS += $(call cc-option, -fno-pie)

あわせてdpg0100/src/Makefileも更新。

CFLAGS += -I$(INCLUDEDIR)
CFLAGS += -fno-pie # 追加
$ make
gcc -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -Wall -Wstrict-prototypes -O -fomit-frame-pointer -pipe -ffreestanding -fno-strict-aliasing -fno-common -I/lib/modules/5.0.0-37-generic/build/include -fno-pie -I/lib/modules/5.0.0-37-generic/build/arch/x86/include -I/lib/modules/5.0.0-37-generic/build/include/asm/mach-default -I/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/mach-generic  -mcmodel=kernel -mno-red-zone -include /lib/modules/5.0.0-37-generic/build/include/generated/autoconf.h -D__SMP__ -DEXPORT_SYMTAB -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(dpg0100)" -D"KBUILD_MODNAME=KBUILD_STR(dpg0100)"   -c -o dpg0100.o dpg0100.c
In file included from /lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/cpufeature.h:5:0,
…
                 from dpg0100.c:9:
/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/processor.h:412:15: error: missing binary operator before token "("
 #if IS_ENABLED(CONFIG_KVM)
               ^
…
/lib/modules/5.0.0-37-generic/build/include/linux/mmzone.h: At top level:
/lib/modules/5.0.0-37-generic/build/include/linux/mmzone.h:147:15: error: missing binary operator before token "("
 #if IS_ENABLED(CONFIG_ZSMALLOC)
               ^
In file included from /lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/realmode.h:15:0,
…
                 from /lib/modules/5.0.0-37-generic/build/include/linux/module.h:13,
                 from dpg0100.c:9:
/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/io.h:44:10: fatal error: asm/early_ioremap.h: そのようなファイルやディレクトリはありません
 #include <asm/early_ioremap.h>
          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
<ビルトイン>: recipe for target 'dpg0100.o' failed
make: *** [dpg0100.o] Error 1

IS_ENABLEDマクロはkconfig.hにあるようなので、インクルード対象に追加。

dpg0100.c
#include <linux/kconfig.h> // 追加

ヘッダファイルが見つからないのは、version.hと同様にリンクすれば解決する。

$ find /usr/src/linux-headers-5.0.0-37-generic/ -name '*ioremap*'
/usr/src/linux-headers-5.0.0-37-generic/arch/x86/include/generated/asm/early_ioremap.h
/usr/src/linux-headers-5.0.0-37-generic/include/config/have/ioremap
/usr/src/linux-headers-5.0.0-37-generic/include/config/generic/early/ioremap.h
$ sudo ln -s /usr/src/linux-headers-5.0.0-37-generic/arch/x86/include/generated/asm/early_ioremap.h /lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/early_ioremap.h
$ # 以下makeやfindするのは省略
$ sudo ln -s /usr/src/linux-headers-5.0.0-37-generic/arch/x86/include/generated/asm/unistd_64_x32.h /lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/unistd_64_x32.h
$ sudo ln -s /usr/src/linux-headers-5.0.0-37-generic/arch/x86/include/generated/asm/unistd_32_ia32.h /lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/unistd_32_ia32.h
$ sudo ln -s /usr/src/linux-headers-5.0.0-37/include/uapi/linux/rseq.h /lib/modules/5.0.0-37-generic/build/include/linux/rseq.h
$ make
…
/lib/modules/5.0.0-37-generic/build/include/linux/signal_types.h: At top level:
/lib/modules/5.0.0-37-generic/build/include/linux/signal_types.h:13:2: error: expected specifier-qualifier-list before ‘__SIGINFO’
  __SIGINFO;
  ^~~~~~~~~
dpg0100.c:20:10: fatal error: asm/system.h: そのようなファイルやディレクトリはありません
 #include <asm/system.h>
          ^~~~~~~~~~~~~~
compilation terminated.
<ビルトイン>: recipe for target 'dpg0100.o' failed
make: *** [dpg0100.o] Error 1

__SIGINFOを定義しているヘッダファイルをインクルードできていない。
siginfo.hを差し替えて対応。

$ sudo mv /usr/include/asm-generic/siginfo.h /usr/include/asm-generic/siginfo.h.bak
$ sudo ln -s /usr/src/linux-headers-5.0.0-37/include/uapi/asm-generic/siginfo.h /usr/include/asm-generic/siginfo.h

<asm/system.h>は現在、いくつかのヘッダファイルに分割されているらしい。
とりあえずコメントに変更し、make。いくつかエラーが出てきたため、修正。

dpg0100.c
//#include <asm/system.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 == 1) {
    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箇所同様に修正

dpg0100.cのコンパイルが通るようになった。

$ make
In file included from /lib/modules/5.0.0-37-generic/build/include/linux/mm_types.h:5:0,
                 from /lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/vdso.h:11,
                 from /lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/elf.h:77,
                 from /lib/modules/5.0.0-37-generic/build/include/linux/elf.h:5,
                 from /lib/modules/5.0.0-37-generic/build/include/linux/elfnote.h:62,
                 from /lib/modules/5.0.0-37-generic/build/include/linux/build-salt.h:4,
                 from dpg0100.mod.c:1:
/lib/modules/5.0.0-37-generic/build/include/linux/mm_types.h: At top level:
/lib/modules/5.0.0-37-generic/build/include/linux/mm_types_task.h:24:13: error: missing binary operator before token "("
   IS_ENABLED(CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK))
             ^
…
/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/irq_vectors.h:102:15: error: missing binary operator before token "("
 #if IS_ENABLED(CONFIG_HYPERV)
               ^
Makefile:309: recipe for target 'dpg0100.mod.o' failed
make: *** [dpg0100.mod.o] Error 1

dpg0100.mod.cが生成されたが、ビルドが通らないため、dpg0100.cと同じように対処。

dpg0100.mod.c
#include <linux/kconfig.h> // 追加
$ make
…
ld -m elf_x86_64 -r -o dpg0100.ko dpg0100.o dpg0100.mod.o
$ sudo make install
mkdir -p /lib/modules/5.0.0-37-generic/misc
cp -f dpg0100.ko /lib/modules/5.0.0-37-generic/misc
$

dpg0100のビルドができました。

カーネル 5.0.37 から 5.3.26 への対応

カーネルの変化でビルドの通し方がちょっと変わった。
以下以外は5.0.37と同じです。

$ sudo ln -s /usr/src/linux-headers-5.3.0-26/include/uapi/linux/time_types.h /lib/modules/5.3.0-26-generic/build/include/linux/time_types.h
$ sudo ln -s /usr/src/linux-headers-5.3.0-26-generic/arch/x86/include/generated/asm/mmiowb.h /lib/modules/5.3.0-26-generic/build/arch/x86/include/asm/mmiowb.h
dpg0100.c
#include <linux/kconfig.h>
typedef long long __kernel_time64_t; // 追加
dpg0100.mod.c
#include <linux/kconfig.h> // 追加( 5.0.37の時も )
typedef long long __kernel_time64_t; // 追加

ロード

$ sudo depmod -a
$ sudo modprobe dpg0100
modprobe: ERROR: could not insert 'dpg0100': Unknown symbol in module, or unknown parameter (see dmesg)
$ dmesg 
...
[ xxx.xxx] dpg0100: module license 'unspecified' taints kernel.
[ xxx.xxx] Disabling lock debugging due to kernel taint
[ xxx.xxx] dpg0100: module verification failed: signature and/or required key missing - tainting kernel
[ xxx.xxx] dpg0100: Unknown symbol init_timer (err -2)
[ xxx.xxx] dpg0100: Unknown symbol sev_enable_key (err -2)
$

うまくロードできない。
init_timer, sev_enable_keyは今使用しているLinuxカーネルでは廃止されているらしい。

init_timertimer_setupに差し替える。

/* コールバック関数、タイマーが切れたときに呼ばれる。 */
static void gpg_timer_fn(struct timer_list *t)
{
    return;
}
void gpg_init_timer(void *timer)
{
        //init_timer((struct timer_list *)timer);
        timer_setup((struct timer_list *)timer, gpg_timer_fn, 0);
        return;
}

sev_enable_keyはコード内に現れない。

$ grep -R sev_enable_key ~/work/PEX-361316/
バイナリファイル xxx/PEX-361316/common/dpg0100/src/dpg0100.o に一致しました
バイナリファイル xxx/PEX-361316/common/dpg0100/src/dpg0100.ko に一致しました
$ grep -R sev_enable_key /lib/modules/5.0.0-37-generic/
...
/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/io.h:extern struct static_key_false sev_enable_key;
/lib/modules/5.0.0-37-generic/build/arch/x86/include/asm/io.h:	return static_branch_unlikely(&sev_enable_key);
...
バイナリファイル /lib/modules/5.0.0-37-generic/kernel/drivers/tty/isicom.ko に一致しました
バイナリファイル /lib/modules/5.0.0-37-generic/misc/dpg0100.ko に一致しました
$ sudo grep -R 'sev_enable_key' /boot/
/boot/System.map-5.0.0-37-generic:ffffffff82417c98 r __ksymtab_sev_enable_key
/boot/System.map-5.0.0-37-generic:ffffffff8241b46b r __kstrtab_sev_enable_key
/boot/System.map-5.0.0-37-generic:ffffffff82b57000 B sev_enable_key
/boot/System.map-5.0.0-23-generic:ffffffff823fd988 r __ksymtab_sev_enable_key
/boot/System.map-5.0.0-23-generic:ffffffff8240113e r __kstrtab_sev_enable_key
/boot/System.map-5.0.0-23-generic:ffffffff82b55000 B sev_enable_key
/boot/System.map-5.3.0-26-generic:ffffffff82454268 r __ksymtab_sev_enable_key
/boot/System.map-5.3.0-26-generic:ffffffff82457b4a r __kstrtab_sev_enable_key
/boot/System.map-5.3.0-26-generic:ffffffff82b75690 B sev_enable_key

カーネル内にsev_enable_keyが含まれているようにみえる。sev_enable_key自体の定義は、EXPORT_SYMBOL_GPL(sev_enable_key);となっている。
そこで、試しに

gpg0100.c
MODULE_AUTHOR("Interface Corporation <http://www.interface.co.jp>");
MODULE_LICENSE("GPL"); // 追加

としてみた。

$ make
$ sudo make install
$ sudo modprobe dpg0100
$ dmesg
[ xxx.xxx] dpg0100:Interface Common Device Driver (Ver2.80.13.00) loaded.
$ lsmod | grep dpg
dpg0100                45056  0

GPLライセンス有効とすれば、利用できるようです。
Wikipediaにある以下の記載に引っかかったようです。

ライセンス問題
Linuxカーネルコミュニティによれば、LKMはカーネルの二次的著作物(derivative works)[12]である。Linuxカーネル開発者はプロプライエタリなモジュールの配布を許容しているが、一部のカーネルシンボルはGPLのモジュールにのみ利用を許している。

GPG-3100のreadme.txtを参照し、
PEX-361316を利用する目的での改変であること、'19年8月でサポートが切れている事から、MODULE_LICENSE("GPL");としても問題ないと前向きに解釈し、進めたいと思います。

本記事を参考にやる方は自己責任でお願いいたします。(ライセンスの話も関わっているので、明記させていただきます。)

CP3100ロード時の問題対処

CP3100をロードすると、Unknown symbol gpg_outl (err -2)など、なぜか参照できないシンボルがある。
色々検索してみると、リンクに課題があるようです。
思い切って、Makefileを以下にしたら解決しました。

Makefile
obj-m = dpg0100.o
all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
install:
	cp -f dpg0100.ko /lib/modules/$(shell uname -r)/misc

参考ページ

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?