Я решил эту проблему (отправленный мной) переустановка alsa-utils
. Я не знаю, является ли это решением, но оно работает на меня.
Как уже говорилось, информация приходит вместе с uname
syscall, информация о котором жестко закодирована в работающем ядре.
Версионная часть обычно устанавливается при компиляции нового ядра с помощью Makefile:
VERSION = 3
PATCHLEVEL = 15
SUBLEVEL = 0
EXTRAVERSION =
, когда у меня было время поиграть с компиляцией моих ядер, я добавлял там вещи в EXTRAVERSION; это давало вам uname -r
с такими вещами, как 3.4.1-mytestkernel
.
Я не до конца понимаю это, но думаю, что остальная информация установлена в Makefile
также вокруг линии 944:
# ---------------------------------------------------------------------------
# KERNELRELEASE can change from a few different places, meaning version.h
# needs to be updated, so this check is forced on all builds
uts_len := 64
define filechk_utsrelease.h
if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then \
echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \
exit 1; \
fi; \
(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\";)
endef
define filechk_version.h
(echo \#define LINUX_VERSION_CODE $(shell \
expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 0$(SUBLEVEL)); \
echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
endef
$(version_h): $(srctree)/Makefile FORCE
$(call filechk,version.h)
include/generated/utsrelease.h: include/config/kernel.release FORCE
$(call filechk,utsrelease.h)
PHONY += headerdep
headerdep:
$(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \
$(srctree)/scripts/headerdep.pl -I$(srctree)/include
Для остальных данных, sys_uname sys_uname
syscall генерируется с помощью макросов (в довольно запутанном виде), вы можете начать с здесь , если вы чувствуете себя авантюристом.
Наверное, лучший способ изменить такую информацию - это написать модуль ядра для переопределения системного вызова uname
; я никогда этого не делал, но вы можете найти информацию на этой странице в разделе 4.2 (извините, прямая ссылка отсутствует). Обратите внимание, однако, что этот код относится к довольно старому ядру (теперь ядро Linux имеет uts
пространства имен, что бы они ни значили), так что вам, вероятно, придется его сильно поменять.
С помощью перекрестной ссылки Linux и вашего упоминания /proc/sys/kernel/ostype
я отследил ostype
до include/linux/sysctl.h,
где комментарий говорит, что имена добавляются вызовом register_sysctl_table
.
Итак, откуда этот вызывается из ? Одним из мест является kernel/utsname_sysctl.c, который включает в себя include/linux/uts.h, где мы находим:
/*. * Определяет, что должна возвращать функция uname() * */ #ifndef UTS_SYSNAME #define UTS_SYSNAME "Linux" #endif
Итак, как указано в документации к ядру :
Единственный способ настроить эти значения - это перестроить ядро
:-)
.Данные хранятся в init/version.c:
struct uts_namespace init_uts_ns = {
.kref = {
.refcount = ATOMIC_INIT(2),
},
.name = {
.sysname = UTS_SYSNAME,
.nodename = UTS_NODENAME,
.release = UTS_RELEASE,
.version = UTS_VERSION,
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
},
.user_ns = &init_user_ns,
.proc_inum = PROC_UTS_INIT_INO,
};
EXPORT_SYMBOL_GPL(init_uts_ns);
Сами строки находятся в include/generated/compile.h:
#define UTS_MACHINE "x86_64"
#define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"
и в include/generated/utsrelease. h:
#define UTS_RELEASE "3.14.0-v2-v"
UTS_SYSNAME может быть определено в include/linux/uts.h
#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif
или как #define в makefiles
Наконец, имя хоста и доменное имя могут управляться /proc/sys/kernel/{hostname,domainname}. Это для пространства имен UTS:
# hostname
hell
# unshare --uts /bin/bash
# echo test > /proc/sys/kernel/hostname
# hostname
test
# exit
# hostname
hell
Утилита uname
получает информацию из системного вызова uname ()
. Он заполняет такую структуру (см. man 2 uname
):
struct utsname {
char sysname[]; /* Operating system name (e.g., "Linux") */
char nodename[]; /* Name within "some implementation-defined
network" */
char release[]; /* Operating system release (e.g., "2.6.28") */
char version[]; /* Operating system version */
char machine[]; /* Hardware identifier */
#ifdef _GNU_SOURCE
char domainname[]; /* NIS or YP domain name */
#endif
};
Это происходит непосредственно из работающего ядра. Я предполагаю, что вся информация жестко закодирована в нем, за исключением, возможно, имени домена
(и, как оказалось, также имени узла
, машины
и ] выпуск
, см. комментарии). Строка выпуска из uname -r
может быть установлена через конфигурацию во время компиляции, но я очень сомневаюсь, что поле sysname может - это ядро Linux, и нет никаких причин для использования чего-либо еще .
Однако, поскольку это открытый исходный код, вы можете изменить исходный код и перекомпилировать ядро, чтобы использовать любое системное имя, какое захотите.
Хотя я не смог найти ничего в источнике, чтобы указать на это, я считаю, что он использует системный вызов uname.
man 2 uname
должен рассказать вам об этом подробнее. Если это так, он получает информацию непосредственно из ядра и ее изменение, вероятно, потребует перекомпиляции.
Вы можете изменить двоичный файл для uname, чтобы делать все, что захотите, просто напишите поверх него с помощью ж / е программы, которая вам нравится. Обратной стороной является то, что некоторые сценарии полагаются на этот вывод.
Правильный способ изменить uname - это изменить заголовки компиляции и перекомпилировать, как предлагали другие. Но я не уверен, почему вы хотите испытывать столько проблем, если вы можете сделать что-то вроде,
alias uname 'uname \\!* | sed s/2.6.13/2.6.52/'
или даже
alias uname 'echo whatever'
Ответ Rmano помог мне на полпути, но настоящее волшебство легче обнаружить, передав параметр Q=
в вашей командной строке make
в исходном каталоге ядра. он позволяет увидеть детали, одна из которых — вызов скрипта:echo "4.4.19$(/bin/sh./scripts/setlocalversion.)"
. выполнение того же фрагмента дает номер версии ядра 4.4.19-00010-ge5dddbf
. если вы посмотрите на скрипт, он определяет номер из системы управления версиями, и запуск его с bash -x
показывает точный процесс:
+++ git rev-parse --verify --short HEAD
++ head=e5dddbf
+++ git describe --exact-match
++ '[' -z '' ']'
++ false
+++ git describe
++ atag=release/A530_os_1.0.0-10-ge5dddbf
++ echo release/A530_os_1.0.0-10-ge5dddbf
++ awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
++ git config --get svn-remote.svn.url
++ git diff-index --name-only HEAD
++ grep -qv '^scripts/package'
++ return
+ res=-00010-ge5dddbf
+ echo -00010-ge5dddbf
-00010-ge5dddbf
Это показывает мне, что если я хочу собрать модуль ядра для работы с моим работающим ядром, я нахожусь на неправильном выпуске с тегами и неправильном коммите. Мне нужно исправить это и собрать по крайней мере DTB (make dtbs
), чтобы создать сгенерированные файлы с правильным номером версии.
оказывается, даже этого было недостаточно. Мне пришлось заменить scripts/setlocalversion
на тот, который просто делает:
#!/bin/sh
echo -0710GC0F-44F-01QA
затем перестройте автоматически сгенерированные файлы:
make Q= ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs
затем я смог собрать образец драйвера Дерека Моллоя и успешно insmod
. по-видимому, предупреждение об отсутствии Module.symvers
не имело значения.все, что Linux использовал, чтобы определить, будет ли модуль работать, было этой строкой localversion.
scripts/mkcompile_h
В v4.19 это файл, который генерирует include/generated/compile.h
и содержит несколько интересных частей/proc/version
:https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_h
Часть #<version>
исходит из файла .version
в дереве сборки, которое увеличивается всякий раз, когда возникает ссылка (требует изменения файла/конфигурации )на scripts/link-vmlinux.sh
.
Его можно переопределить KBUILD_BUILD_VERSION
переменной окружения:
if [ -z "$KBUILD_BUILD_VERSION" ]; then
VERSION=$(cat.version 2>/dev/null || echo 1)
else
VERSION=$KBUILD_BUILD_VERSION
fi
дата просто необработанная date
звонок:
if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
TIMESTAMP=`date`
else
TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
fi
и аналогично имя пользователя происходит отwhoami
(KBUILD_BUILD_USER
)и имя хоста отhostname
(KBUILD_BUILD_HOST
)
Версия компилятора взята из gcc -v
и, похоже, не поддается контролю.
Вот как изменить материальную версию вопроса:https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot