FAQ SynocliKernel (usbserial, linuxtv) - SynoCommunity/spksrc GitHub Wiki
A package called synocli-kernel
provides lower-level USB helpers and scripts to help upon module loading and unloading. This package should normally be a hard dependency to any other kernel module related package. To do so in spk/<package>/Makefile
should include SPK_DEPENDS = synocli-kernel
variable. Module loading helper script can be called with --help --verbose
in order to get additional details:
./synocli-kernelmodule.sh --spk synokernel-usbserial --config synokernel-usbserial.cfg:ch341,cp210x --verbose --udev 60-synokernel-usbserial.rules status --help
./synocli-kernelmodule.sh (verbose)
SynoCommunity kernel driver package name (SPK) [synokernel-usbserial]
SynoCommunity configuration file (SPK_CFG) [synokernel-usbserial.cfg]
SynoCommunity configuration path (SPK_CFG_PATH) [/var/packages/synokernel-usbserial/target/etc]
SynoCommunity configuration option (SPK_CFG_OPT) [ch341,cp210x]
Synology NAS arch (ARCH) [apollolake]
Synology DSM version (DSM_VERSION) [6.2.4]
Running kernel version (KVER) [4.4.59+]
Module action insmod|rmmod|reload|status (ACTION) [status]
Kernel modules path (MPATH) [/var/packages/synokernel-usbserial/target/lib/modules]
Full kernel modules path (KPATH) [/var/packages/synokernel-usbserial/target/lib/modules/apollolake-6.2.4/4.4.59+]
Device firmware path (FPATH) [/var/packages/synokernel-usbserial/target/lib/firmware]
udev rules.d path (UPATH) [/var/packages/synokernel-usbserial/target/rules.d]
udev rules.d file (URULE) [60-synokernel-usbserial.rules]
Kernel objects list (KO_LIST) [usbserial ch341 cp210x]
Kernel objects found (KO_PATH) [/drivers/usb/serial/usbserial.ko /drivers/usb/serial/ch341.ko /drivers/usb/serial/cp210x.ko]
Usage : ./synocli-kernelmodule.sh [-s|--spk <package>] [<insmod,start|rmmod,stop|reload,restart|status>] module1.ko module2.ko ...
Optional : [-c|--config <file>:<option1>,<option2>,...]
[-u|--udev <file>]
[-s|--spk <package>] : SynoCommunity package name containing kernel modules
[<insmod|rmmod|reload|status>] : Action to be performed
[-h|--help] : Print this help
[-v|--verbose] : Verbose mode
Examples :
./synocli-kernelmodule.sh --spk synokernel-cdrom --verbose cdrom sr_mod status
./synocli-kernelmodule.sh --spk synokernel-cdrom --config synokernel-cdrom.cfg:default status
./synocli-kernelmodule.sh --spk synokernel-usbserial --udev 60-synokernel-usbserial.rules usbserial ch341 cp210x status
./synocli-kernelmodule.sh --spk synokernel-usbserial --config synokernel-usbserial.cfg:ch341,cp210x status
This is a basic simple kernel module package that can used as example. It provides cdrom.ko
and sr_mod.ko
kernel modules that can be used to connect USB based CD-ROM to your NAS using the synocli-kernel
helper script such as:
./synocli-kernelmodule.sh --spk synokernel-cdrom --config synokernel-cdrom.cfg:default insmod
dmesg
output should provide something similar to:
[3553418.051365] usb 2-1: new SuperSpeed USB device number 2 using xhci_hcd
[3553418.069471] usb 2-1: LPM exit latency is zeroed, disabling LPM.
[3553418.077353] usb-storage 2-1:1.0: USB Mass Storage device detected
[3553418.084541] scsi host6: usb-storage 2-1:1.0
[3553419.104008] scsi 6:0:0:0: CD-ROM PIONEER BD-RW BDR-XD05 3.01 PQ: 0 ANSI: 0
[3553419.114808] scsi 6:0:0:0: Attached scsi generic sg5 type 5
[3790953.029269] sr 6:0:0:0: [sr0] scsi3-mmc drive: 62x/62x writer dvd-ram cd/rw xa/form2 cdda tray
[3790953.039237] cdrom: Uniform CD-ROM driver Revision: 3.20
[3790953.045785] sr 6:0:0:0: Attached scsi CD-ROM sr0
Unloading the module using:
./synocli-kernelmodule.sh --spk synokernel-cdrom --config synokernel-cdrom.cfg:default rmmod
Will produce following output to dmesg
:
[3790963.004714] cdrom: Uniform CD-ROM driver unloaded
This relatively simple kernel module package also includes udev
rules to get access to the needed device file with proper permissions. It provides usbserial.ko
, ch341.ko
, cp210x.ko
, pl2303.ko
, ti_usb3410_5052.ko
and ftdi_sio.ko
kernel modules that can be used to connect a USB-Serial adapter. synocli-kernel
helper script can be used such as:
./synocli-kernelmodule.sh --spk synokernel-usbserial --config synokernel-usbserial.cfg:ch341,cp210x --udev 60-synokernel-usbserial.rules start
dmesg
output should provide something similar to:
[3994283.661384] usbcore: registered new interface driver usbserial
[3994283.695707] usbcore: registered new interface driver ch341
[3994283.702615] usbserial: USB Serial support registered for ch341-uart
[3994283.731617] usbcore: registered new interface driver cp210x
[3994283.738064] usbserial: USB Serial support registered for cp210x
Unloading the module using:
./synocli-kernelmodule.sh --spk synokernel-usbserial --config synokernel-usbserial.cfg:ch341,cp210x rmmod
Will produce following output to dmesg
:
[3994653.045224] usbserial: USB Serial deregistering driver cp210x
[3994653.052259] usbcore: deregistering interface driver cp210x
[3994653.080559] usbserial: USB Serial deregistering driver ch341-uart
[3994653.087806] usbcore: deregistering interface driver ch341
[3994653.113854] usbcore: deregistering interface driver usbserial
This package applies https://linuxtv.org/ media-tree backport code over Synology's kernel source code in order to produce updated USB DVB driver modules. This allows compatibility with newer USB DVB devices with recent Synology NAS (more information below).
IMPORTANT: synokernel-linuxtv
package is not compatible with VideoStation DTV advanced function.
You must disable the option in VideoStation under Settings
(tab) -> DTV
-> Advanced
-> Disable the DTV function
. Otherwise this will change the value of /lib/udev/script/DTV_enabled
to yes
and trigger /lib/udev/script/usb-dvb-util.sh
to load all Synology default DVB modules. Theses modules will conflict with synokernel-linuxtv
and may result in kernel crash.
If this option is already set:
- activate the checkbox in order to disable the option (yes, you enable disabling of...)
- reboot your system to flush out any default Synology DVB loaded modules from memory
- install or activate
synokernel-linuxtv
- check out the logs under
/tmp/synocli-kernelmodule-synokernel-linuxtv.log
- if you require assistance provide output from script
/var/packages/synocli-kernel/target/bin/synocli-kernelmodule-dbg.sh
that will result in a log file under the/tmp
directory such assynocli-kernelmodule-dbg.20210224-0118.log
Synology provides source code for the running kernel only after the release of the subsequent DSM version. Therefore in order to build kernel driver modules matching running kernel you must be running an older version of DSM (for instance continue using 6.2.3 while 6.2.4/7.0 are out).
While building is automated under the hood the package creation process is rather complex as it:
- Invoke
REQUIRE_KERNEL=1
to prepare the kernel for module building - Refers to
DEPENDS=cross/linuxtv
from where it download the media-tree based on the kernel version (TC_KERNEL
). As of January 2021 the oldest supported kernel is version 4.4 (e.g. newest offered by Synology as of DSM-6.2.3 and DSM-7.0). Older kernel support up to version 3.10 was removed in Jan2021. Therefore, depending of the kernel version the package will be built either using the latest snapshot (>=4.4) or using latest compatible version as of 2021-01-13 (=3.10) - Downloads latest DVB firmware snapshot (https://www.linuxtv.org/downloads/firmware/)
- Downloads latest backport patches to be applied over the media-tree for kernel compatibility (https://linuxtv.org/downloads/drivers/)
- Applies various patches over the resulting media-tree snapshot so it is compatible with Synology's modified kernel version
- Use a
BLACKLIST
to avoid building any PCI devices or drivers that result in build failures - Use a
WHITELIST
to add additional USB DVB modules otherwise left aside - Build all the configured modules (as per
v4l2/.config
) - Install the modules and generate a dynamic
PLIST
to match resulting modules - Create packages
The process of adding your devices the list of supported USB DVB devices shouldn't be to much of an issue for Linux enthusiast. Basically all it requires is to:
- Install
synocli-kernel
andsynokernel-linuxtv
packages - using
insmod
andrmmod
to load the various modules (located under/var/packages/synokernel-linuxtv/target/lib/modules/
) needed to make your device to be detected. List of devices available here:
- https://linuxtv.org/wiki/index.php/DVB-C_USB_Devices
- https://linuxtv.org/wiki/index.php/ATSC_USB_devices
- once the proper set of modules and right order is found, it can be applied to the configuration files. First you need to STOP
SynoKernel LinuxTV media drivers
package from the Package Center - adjust the configuration file for necessary modules to be loaded in:
/var/packages/synokernel-linuxtv/target/etc/synokernel-linuxtv.cfg
- set an equivalent variable name to "
true
" under:/var/packages/synokernel-linuxtv/target/etc/synokernel-linuxtv.ini
- test the START|STOP of the package from the Package Center
- follow the log output under
/tmp/synocli-kernelmodule-synokernel-linuxtv.log
Kernel dependency usage is called using REQUIRE_KERNEL = 1
.
Automated building of modules is done through REQUIRE_KERNEL_MODULE
such as:
REQUIRE_KERNEL_MODULE = CONFIG_USB_SERIAL_OPTION:drivers/usb/serial:usbserial
REQUIRE_KERNEL_MODULE += CONFIG_USB_SERIAL_CH341:drivers/usb/serial:ch341
...
Each configuration option is a result of 3x sub-variables:
- Kernel configuration option
- Kernel directory tree where this module is located
- Actual module name (ending
.ko
omited)
When REQUIRE_KERNEL_MODULE
is not empty, kernel modules ends-up being compiled & installed by spksrc.kernel.mk
spksrc framework makefile helper. The installation location reflects a default kernel installation path (normally under /lib/modules
) being package under install/var/packages/synokernel-usbserial/target/lib/modules
under a sub-directory corresponding to the kernel version (i.e. equivalent to uname -r
on NAS) such as :
modules
└── 4.4.59+
└── kernel
└── drivers
└── usb
├── class
│ └── cdc-acm.ko
└── serial
├── ch341.ko
├── cp210x.ko
├── ...
In order at installation time to select the modules needing to be loaded, an installation/upgrade helper is being demonstrated within the synokernel-usbserial
package. It consists of two main configuration files:
-
src/synokernel-usbserial.cfg
: Consists of all the modules including their directory tree starting underkernel/drivers/
path. -
src/synokernel-usbserial.ini
: Consists of all modules required status, enabled or not (i.e.true
orfalse
). This file is being generated automatically from the GUI selection through theservice-setup.sh
scripts as called bySERVICE_SETUP = src/service-setup.sh
variable.
There are two DSM dialog configuration files:
-
src/wizard/install_uifile
: Contains each checkbox configuration so the DSM shows the dialog window. -
src/wizard/upgrade_uifile.sh
: Almost identical toinstall_uifile
but in a for of a script where"defaultValue": $<variable>
are being set to their previous values.
And one service script:
-
src/service-setup.sh
: Script being called at installation time (pre/post install/upgrade). This script will gather the DSM GUI selector variable values and write them tosynokernel-usbserial.ini
configuration file.
Variable names must match in all resulting files (.cfg
, .ini
and *uifile*
) for it to work properly.
At installation time, DSM will output a module selection window allowing to check each modules to be loaded. This GUI is configured through the spk/<package>/src/wizard
directory through the install_uifile
file such as:
[{
"step_title": "SynoKernel USB Serial kernel module configuration",
"items": [{
"type": "multiselect",
"subitems": [{
"key": "default",
"desc": "USB Serial (usbserial.ko)",
"disabled": true,
"defaultValue": true
},
{
"key": "ch341",
"desc": "Winchiphead CH341 USB-RS232 Converter (ch341.ko)",
"defaultValue": false
},
{
"key": "cdc_acm",
"desc": "CDC-ACM - Communication Device Class Abstract Control Model (cdc-acm.ko)",
"defaultValue": false
}]
}]
}]
At upgrade time the file is slightly different as ran as a script upgrade_uifile.sh
in order to adjust all the defaultValue
to its corresponding real value from the previous installation:
#!/bin/sh
set +x
CFG_FILE="/usr/local/${SYNOPKG_PKGNAME}/etc/${SYNOPKG_PKGNAME}.ini"
. ${CFG_FILE}
FIRST=`/bin/cat<<EOF
{
"step_title": "SynoKernel USB Serial kernel module configuration",
"items": [{
"type": "multiselect",
"subitems": [{
"key": "default",
"desc": "USB Serial (usbserial.ko)",
"disabled": true,
"defaultValue": true
},
{
"key": "ch341",
"desc": "Winchiphead CH341 USB-RS232 Converter (ch341.ko)",
"defaultValue": false
},
{
"key": "cdc_acm",
"desc": "CDC-ACM - Communication Device Class Abstract Control Model (cdc-acm.ko)",
"defaultValue": false
}]
}]
}
EOF`
echo "[$FIRST]" > $SYNOPKG_TEMP_LOGFILE
exit 0
Post installation the updated variables will be written to /usr/local/${SYNOPKG_PKGNAME}/etc/${SYNOPKG_PKGNAME}.ini
. This action is triggered by the service-setup.sh
script being called post-installation and post-upgrade:
write_config() {
echo "default=true" > ${INI}
for option in $(cat ${CFG}); do
var=${option%%=*}
echo "${var}=${!var}" >> ${INI}
done
}
The default service helper script is assigned through the variable SSS_SCRIPT = src/dsm-control.sh
in the spk Makefile. The script at packaging time is being renamed to /var/packages/synokernel-<package>/scripts/start-stop-status
.
It will look for each variable being set to true
in the .ini
file and load a $KO
variable with all corresponding kernel objects found in the .cfg
file, always starting with default
in terms of ordering. This script then calls /usr/local/bin/synocli-kernelmodule
with all the necessary arguments (part of synocli-kernel
package).
This script is intended to be as generic as possible so it works as-is for other kernel packages uses cases (currently being used for both synokernel-usbserial
and synokernel-linuxtv
).
The synocli-kernel
package provides the generic /usr/local/bin/synocli-kernelmodule
script to help at loading/unloading/status of each modules. This script expects all modules to be provided as argument in the appropriate order and ensures to keep that order for loading and reverse it for unloading of modules. Help output:
Usage : /usr/local/bin/synocli-kernelmodule [-m <path> ] [-a <load|unload|status>] module1.ko module2.ko ...
Optional : [-f <path>] [-k <version> ] [-n <name>]
[-m <path> ] : Kernel module base path (OPTIONAL if -n <package> is provided)
[-f <path> ] : Additional firmware base path (OPTIONAL)
[-k <path> ] : Kernel version (OPTIONAL: uses `uname -r` if not provided)
[-n <package> ] : Name of the SynoCommunity package invoking this script for logging purpose
[-a <load|unload|status> ] : Action to be performed
Example :
/usr/local/bin/synocli-kernelmodule -a load -k 4.4.59+ \
-m /var/package/synokernel-usbserial/target/lib/modules \
usb/serial/usbserial.ko usb/serial/ftdi_sio.ko
The output is always being redirected for DEBUG purpose into /tmp/synocli-kernelmodule-<package-name>.log
such as:
Status of kernel modules...
usb/serial/usbserial.ko [usbserial] OK
usb/serial/ch341.ko [ch341] OK
usb/class/cdc-acm.ko [cdc_acm] OK
usb/serial/ti_usb_3410_5052.ko [ti_usb_3410_5052] OK
synokernel-usbserial is running
It can manage the addition of alternate firmware loading path such as for synokernel-linuxtv
:
synokernel-linuxtv is running
Status of kernel modules...
media/rc/rc-core.ko [rc_core] OK
media/mc/mc.ko [mc] OK
media/v4l2-core/videodev.ko [videodev] OK
media/common/tveeprom.ko [tveeprom] OK
media/common/videobuf2/videobuf2-common.ko [videobuf2_common] OK
media/common/videobuf2/videobuf2-v4l2.ko [videobuf2_v4l2] OK
media/common/videobuf2/videobuf2-memops.ko [videobuf2_memops] OK
media/common/videobuf2/videobuf2-vmalloc.ko [videobuf2_vmalloc] OK
media/dvb-core/dvb-core.ko [dvb_core] OK
media/tuners/si2157.ko [si2157] OK
media/dvb-frontends/lgdt3306a.ko [lgdt3306a] OK
media/usb/em28xx/em28xx.ko [em28xx] OK
media/usb/em28xx/em28xx-dvb.ko [em28xx_dvb] OK
Status of optional firmware path...
[/var/packages/synokernel-linuxtv/target/lib/firmware/] OK
synokernel-linuxtv is running