我有一个场景,我需要在内核更新后重新编译我的显示驱动程序。我正在尝试在启动时使用 Bash 脚本使其自动化。因此,我需要一种方法来知道我的内核已更改,并为新运行的内核重新安装驱动程序。
我正在考虑在第一次安装驱动程序时将内核版本输出到文件中,并在我的脚本中始终检查该文件内容是否与现在安装的内容不同。
这是正确的方法吗?我将不胜感激任何关于如何知道自从我上次安装驱动程序以来内核是否发生变化的建议。
- 我知道有 DKMS,这正是它的用途,但它并不总是有效,所以我想以不同的方式做到这一点。
答案1
您可以简单地运行uname -mrs
来查看版本是否已更改,但您也可以dpkg --list | grep linux-image
检查所有已安装内核的列表。
答案2
在启动时使用 bash 脚本实现自动化
自动化...是的,但不是在启动期间?内核更新后,您必须重新启动。之前,关机。所以你应该知道它什么时候发生。或者我错过了什么。准备好该脚本以使用一个命令进行切换(编译),但不要在新内核第一次启动时进行。
就像必须处理模块一样(通过 make direct,通过发行版,您还可以从其中获得新的 initrd ),如果您有特定于驱动程序的内核版本,那么它属于清单而不是引导脚本。否则,naw 的风险太大(= 并不总是有效:-)
uname -r
提到了......但是将其存储在文件中并检查它?
放置信息和进行内核版本驱动程序控制的地方可以是引导脚本。几个月后它可能看起来像
# 4.1.0 dispdr=firstone
# 4.2.0 dispdr=second_driver
# 4.4.0
dispdr=third
# next version probably 4.6.0
这是透明且可逆的。显然,我对这些司机一无所知。
答案3
至于一般问题:“在内核更改的情况下如何做某事”我同意你的观点,我也会做类似的事情:
program=my_system_version_checker
state_file=/var/lib/${program}/version
if [ -r "$state_file" ]; then
last_version=$( cat "$state_file" )
else
last_version="unknown"
fi
current_version=$(uname -r) # or may be uname -a or anything else you'd like
if [ $? -ne 0 ]; then
exit 1 # Handle case when we can't get current_version for some reason
fi
if [ "$last_version" != "${current_version}"]; then
make LAST_VERSION="$last_version" CURRENT_VERSION=${current_version} -C /opt/${program} update
fi
[ -d $(dirname $state_file) ] || mkdir -p $(dirname $state_file)
echo "$current_version" > "$state_file"
并将其放在启动脚本中以在每次启动时运行(使用 systemd 单元文件或 upstart 或其他任何内容取决于您的系统和启动管理器)。
但至于以这种方式重建内核模块,我认为这不是一个好主意,因为您可能会用新的驱动程序破坏某些东西,并且您会在下次启动时知道它,或者您可以rmmod/insmod
在脚本中添加逻辑,这也可能不安全跑步。因此,我最好使用一些类似于DPkg::Post-Invoke
for的钩子apt
在内核更新后运行我的脚本。
答案4
我正在将文件/boot
与uname -r
此处进行比较。几个月来,它对我来说一直运行良好:
#!/bin/bash
cd /boot || exit 1
shopt -s nullglob ; for file in config-* ; do kernels+=( "${file#config-}" ) ; done
newest="$(printf '%s\n' "${kernels[@]}" | sort -V -t - -k 1,2 | tail -n1)"
current="$(uname -r)"
[[ $current != $newest ]] && echo "Reboot needed for new kernel"
我已经在 Debian 和基于 RHEL 的发行版上对其进行了测试。