编译群晖的驱动
首先要有一个linux环境,可以是群晖的dsm或ubuntu,或debian
先下载 toolchain
选择版本后,下载对应平台的文件

选择版本后,先择linux-开头的对应内核版本的文件

root账户权限,使用winscp连接环境系统后,
安装所需软件:
plaintext
apt-get install build-essential
apt-get install libncurses-dev
apt-get install bison
apt-get install flex
apt-get install libssl-dev
apt-get install libelf-dev
apt-get install libncurses5-dev
apt-get install bc
apt-get install dialog
apt-get install dpkg-dev
apt-get install autocon创建一个工作目录,例如在home里创建syno
plaintext
mkdir /home/syno上传toolchain文件到工作目录:

使用下面命令,解压文件到当前目录
plaintext
tar -xvf *.txz解压后,进入解压后的目录,上传GPL sources文件,

再次使用解压命令解压到当前文件夹
plaintext
cd x86_64-pc-linux-gnu
tar -xvf *.txz进入解压后的目录,不同内核版本目录不同
plaintext
cd linux-4.4.x
复制平台对应的配置文件到此目录,
4.4内核的配置文件在synoconfigs目录内
5.1内核的配置文件在synology/synoconfigs

plaintext
cp synoconfigs/geminilake .config菜单化修改配置文件
plaintext
make menuconfig找到需要编译的驱动,按空格键切换为

保存后,创建环境,及执行清理文件,编译工作
plaintext
# 平台,x86或arm64
export ARCH=x86
# 工具路径,在上一级的bin目录
export CROSS_COMPILE=[前面的路径补全]/bin/x86_64-pc-linux-gnu-
# 清理
make clean
# 执行编译,j值为编译工作调用核心数
make modules -j4如只需编译指定类型的驱动可使用M参数指定目录
plaintext
make modules M=./drivers/hwmon -j4编译后的文件在路径drivers下面对应的分类里。
如螃蟹网卡驱动在这里:

关于编译时候报错:
plaintext
subcmd-util.h: In function ‘xrealloc’:
subcmd-util.h:58:31: error: pointer ‘ptr’ may be used after ‘realloc’ [-Werror=use-after-free]
58 | ret = realloc(ptr, 1);
| ^~~~~~~~~~~~~~~
subcmd-util.h:52:21: note: call to ‘realloc’ here
52 | void *ret = realloc(ptr, size);
| ^~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors代码原因
旧版本 Linux 的 linux-5.10.x/tools/lib/subcmd/subcmd-util.h 里写法有点问题,realloc 后还用 ptr,新编译器严格检查时会触发警告。
解决办法
编辑出错的文件:
tools/lib/subcmd/subcmd-util.h
找到这一段,大概在L50:
plaintext
static inline void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret) {
ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret)
die("Out of memory, realloc failed");
}
return ret;
}改为:
plaintext
static inline void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(NULL, 1);
if (!ret) {
ret = realloc(NULL, size);
if (!ret && !size)
ret = realloc(NULL, 1);
if (!ret)
die("Out of memory, realloc failed");
}
return ret;
}再重新编译即可