Прежде всего, tty, даже если он кажется единым файловым объектом, на самом деле представляет собой пару каналов/очередей, --один для вывода и один для ввода, другие концы каждого из которых подключены либо к TX/RX какого-либо аппаратного устройства или доступ к другой программе в случае псевдотерминала -. Когда вы записываете что-либо в fd, связанный с tty, вы записываете в очередь вывода , даже если это fd 0 (stdin )вашего процесса, и не будет возвращается в очередь ввода .
В большинстве систем Unix (, за заметным исключением OpenBSD ), существует специальный ioctl (TIOCSTI
), который позволяет вставлять байт во входную очередь tty, как если бы он был получен. с другого конца. TIOCSTI
будет работать от имени пользователя root только в том случае, если он не используется на управляющем tty вызывающего его процесса.
$ cc -Wall tiocsti.c -o tiocsti
--как корень--
# printf '\04' |./tiocsti >/proc/5460/fd/0
Если ваш процесс выполняется на псевдо-tty, другой способ «фальсификации» ввода — подключиться с помощью отладчика к процессу, содержащему главную сторону псевдо--tty, и write(2)
ваши данные. в него оттуда.
$ gdb -p pid_of_xterm
(gdb) p write(4, "\x04", 1) # 4 is the fd of the master pty
(gdb) c
Оба метода просто излишни . Если вы хотите контролировать запущенный процесс, вам лучше подключиться к этому самому процессу с помощью отладчика, а не подделывать его ввод; если вы хотите инструментализировать интерактивную программу, вам лучше запустить ее в expect
; оба будут работать в любой системе Unix и не требуют для этого дополнительных привилегий.
Также обратите внимание, что ^D
/ \004
будет работать как EOF
, только если a)tty находится в каноническом режиме b)специальный символ c_cc[VEOF]
не был изменено на что-то другое c)очередь вывода пуста (иначе c_cc[VEOF]
придется отправить дважды ). И, конечно же, это будет процесс, который просто читает из tty, который получит EOF или эти байты, не обязательно оболочка.
tiocsti.c
#include
#include
#include
int main(void){
char c; ssize_t r;
while((r = read(0, &c, 1)) > 0){
if(ioctl(1, TIOCSTI, &c)) err(1, "ioctl(TIOCSTI)");
}
if(r < 0) err(1, "read");
return 0;
}
Со временем сам процесс компиляции ядра Linux получил дальнейшее развитие. Он стал более сложным, но и более упорядоченным. Запустите make help
в исходном каталоге ядра, чтобы увидеть список всех целей make
и краткие пояснения по каждой из них.
В текущей серии ядер 5.x команды make
и make all
эквивалентны :обе они будут запускать специфичный для архитектуры -список целей по умолчанию.
В аппаратной архитектуре x86 список по умолчанию содержит:
make vmlinux
для сборки чистого ядра (это также выполняется автоматически, если вы запустите make bzImage
, так как перед тем, как вы сможете создать сжатый загрузочный файл образа ядра, вам сначала нужно сделать то, что вы хотите сжать ; несжатая версия также полезна для некоторых инструментов отладки ядра.)make modules
для сборки модулей ядра make bzImage
, чтобы создать загрузочный сжатый файл образа ядра. Все вышеперечисленное можно выполнить от имени обычного пользователя без дополнительных привилегий.
С другой стороны, make install
будет использовать либо ~/bin/installkernel
, либо /sbin/installkernel
, если они существуют. Ваш собственный ~/bin/installkernel
может включать использование sudo
или аналогичного, где это применимо, но система /sbin/installkernel
обычно написана так, чтобы ожидать, что у вас уже есть root-доступ.
Аналогично,make modules_install
скопирует модули новой версии ядра в дерево каталогов /lib/modules/<kernel_version>/
, поэтому для успешной работы потребуется root-доступ.
Лучше всего избегать запуска длительных и сложных процессов (, таких как компиляция ядра! )от имени пользователя root, если в этом нет особой необходимости, текущий минимальный процесс компиляции ядра будет выглядеть примерно так:
make
или make all
как обычный пользователь sudo make modules_install
для установки модулей ядра sudo make install
, чтобы установить актуальное ядро. Я бы рекомендовал делать это в последнюю очередь, так как /sbin/installkernel
может вызвать другие операции, такие как автоматическая сборка файла initramfs, и эти другие операции будут более успешными, если новые модули ядра уже установлены. Но если вы занимаетесь разработкой ядра, а не просто настраиваете ядро для собственных нужд, вы можете использовать более -детализированный процесс; например, если вы разрабатываете модуль ядра, вы можете запустить make modules
как отдельный шаг, чтобы вам было легче увидеть, не произошел ли сбой из-за сделанной вами ошибки, и вы могли быстрее приступить к исправлению ошибки.. После исправления ошибки вы сможете просто перейти к повторному запуску make modules
, так как предыдущие шаги уже успешно выполнены.
Точно так же разработчик, работающий с ранним запуском ядра -, может просто захотеть получить bzImage для тестирования в другой системе (с хитрым набором таблиц ACPI или чем-то еще ), и не заботиться о модули вообще.