Нужна ли для работы ядра Linux файловая система?

Ejecutar eso sudo -i echo $'line1\nline2'bajo strace muestra que Bash comienza así:

9183  execve("/bin/bash", ["-bash", "--login", "-c", "echo line1\\\nline2\\\n"],...

Ahora, stracepresenta caracteres especiales con una barra invertida -cuando muestra las cadenas, por lo que lo que Bash realmente obtiene como argumento para -ces echo line1[backslash][newline]line2[backslash][newline]y para el shell, una barra invertida al final de una línea marca una línea de continuación y elimina la barra invertida y la nueva línea siguiente.

Sin -i, sudoejecuta echodirectamente, sin atravesar el caparazón:

9189  execve("/bin/echo", ["echo", "line1\nline2\n"],... 

Aquí, esa es una nueva línea literal que va a echo, y echolo imprime debidamente.


La ​​idea aquí debe ser que sudointente agregar una capa de escape de shell para acomodar el hecho de que sh -ctoma una única cadena , mientras que sudotoma el comando como distinto argumentos.

Compare los siguientes casos:

sudoescapa del espacio (este es solo el nombre del comando, ¡sin argumentos!):

$ sudo -i 'echo foo'
-bash: echo foo: command not found

sudoescapa de la barra invertida, por lo que esto realmente funciona (Bash's echono procesa la barra invertida):

$ sudo -i echo 'foo\bar'
foo\bar

Lo mismo con una pestaña:

$ sudo -i echo $'foo\tbar'
foo     bar

Aquí, no hay comillas adicionales en la barra invertida, por lo que Bash lo elimina mientras procesa la línea de comando de shell(bno es un carácter especial para el shell,y no necesita cotización. Esto es básicamente lo mismo quebash -c 'echo foo"b"ar'):

$ bash -c 'echo foo\bar'
foobar

El problema es que no se puede escapar de una nueva línea con una barra invertida, y sudono parece tener eso en cuenta.

En cualquier caso, citar problemas como este probablemente sea un poco más fácil si almacena los comandos que desea en un archivo y lo ejecuta como un script.

19
01.08.2019, 22:45
4 ответа

Это довольно странный вопрос, потому что вы не запускаете ядро ​​так же, как запускаете программу.Ядро — это платформа для запуска программ. Конечно, есть код установки и завершения работы, но запустить ядро ​​самостоятельно невозможно. Всегда должен быть основной процесс "init". И ядро ​​будет паниковать, если его там нет. Если init попытается завершить работу, ядро ​​также запаникует.

В наши дни процесс инициализации похож на systemd. Если не указано иное, ядро ​​попытается запустить программу из списка местоположений, начинающихся с /sbin/init. См. параметр инициализации здесь http://man7.org/linux/man-pages/man7/bootparam.7.html. В экстренной ситуации вы можете загрузить Linux с init=/bin/bash. Но обратите внимание, как вы всегда указываете файл в файловой системе для запуска.

Таким образом, ядро ​​будет паниковать, если запустится без файловой системы, потому что без нее невозможно загрузить init.

Некоторая путаница может возникнуть из-за фазы инициализации ядра. Начальный виртуальный диск загружается из образа на диске, содержащего жизненно важные драйверы и сценарии установки. Они выполняются до загрузки файловой системы. Но не заблуждайтесь, исходный виртуальный диск сам по себе является файловой системой. На начальном виртуальном диске /initвызывается (, который хранится на начальном виртуальном диске ). Во многих дистрибутивах именно это вызывает /sbin/init. Опять же без файловой системы это невозможно.

28
27.01.2020, 19:44

В Linux почти каждое устройство является файлом , так что для его запуска необходима файловая система.

3
27.01.2020, 19:44

Ядро ЯВЛЯЕТСЯ программой, как и любая другая. По умолчанию ядро ​​​​Linux пытается получить доступ к файловой системе, однако это поведение может быть тривиально устранено модификацией ядра (, на самом деле просто добавлением функции «arch _call _rest _init ()» ). Для выполнения «полезной работы» мы ожидаем, что разработчик может включить потоки ядра (kthreads ), возможно, в пользовательский драйвер,для выполнения некоторой желаемой рабочей нагрузки по инициализации и типу приложения. Ядро Linux уже содержит множество k-потоков, но в основном для выполнения вспомогательной работы по отношению к ядру или драйверам. API-интерфейсы, доступные в контексте ядра, сильно отличаются от доступных в пользовательском -пространстве Linux. Большая часть функциональных возможностей системных вызовов стала бы бесполезной в сценарии без файловой системы -.

Да, Linux по умолчанию требует доступа к файловым системам. Нет, модифицированное ядро, безусловно, может выполнять полезную работу без какой-либо файловой системы. Практическое использование Linux без файловой системы, по IMO, довольно ограничено, но не равно нулю. FWIW, в прошлом многие ядра -реального времени были встроены в то же -пространство имен и двоичные файлы, что и приложения RT.

0
27.01.2020, 19:44

Ответ будет зависеть от того, имеете ли вы в виду буквально без файловой системы, или вопрос должен быть истолкован немного иначе, чем он фактически сформулирован. Ответы для небольших вариаций в том, как интерпретируется вопрос:

  • Запуск Linux без каких-либо блочных устройств вполне осуществим и полезен для некоторых особых случаев использования.
  • Запуск Linux без какой-либо файловой системы потребует переписывания некоторых частей кода ядра, и вряд ли это будет полезно.
  • Запуск Linux без использования каких-либо файловых дескрипторов потребует больших усилий. Я почти уверен, что это не будет стоить усилий.

Причины, по которым вам придется переписывать части кода ядра, чтобы сделать работающую систему без файловой системы,:

  • Каждый поток имеет корневой каталог и текущий рабочий каталог, который должен указывать на некоторую файловую систему.
  • Программы запускаются системным вызовом execve, которому требуется исполняемый файл из файловой системы.
  • В процессе загрузки ядро ​​создает файловую систему в памяти.

После того, как программа была запущена с помощью execve, она может отменить отображение исполняемого файла, из которого она была запущена, хотя для того, чтобы сделать это без немедленного сбоя, сначала необходимо создать исполняемое отображение памяти, которое не t поддерживается файлом, и он должен инициализировать его некоторым полезным кодом, прежде чем перейти к нему и отменить отображение исполняемого файла.

Таким образом, работающая программа пользовательского режима может существовать в состоянии, когда у нее нет отображений памяти, поддерживаемых файлами, и она может закрыть все файловые дескрипторы, поддерживаемые файлами. Он не может отказаться от корневого каталога и текущего рабочего каталога, но может воздержаться от них.

Таким образом, хотя в этом состоянии вы можете реализовать код ядра, чтобы вырвать файловую систему из-под программы и заставить ее продолжать работать, это не кажется полезным. И переход в это конечное состояние без прохождения промежуточного состояния использования файловой системы будет еще более трудоемким без какой-либо полезной пользы.

Полезная настройка для некоторых специализированных вариантов использования

Может быть полезно избегать использования блочных устройств. Во время загрузки ядро ​​создает файловую систему в памяти, а также может заполнить эту файловую систему содержимым из архива cpioперед выполнением init. Таким образом, вы можете полностью запустить систему из файловой системы в памяти без какого-либо блочного устройства для ее поддержки.

Это может быть полезно для систем, в которых вы не хотите сохранять какое-либо состояние и хотите, чтобы система запускалась с чистого листа после перезагрузки.

Конечно, ядро ​​и архив cpio должны каким-то образом существовать в памяти, прежде чем ядро ​​получит управление. Как они туда попали - это работа для загрузчика. Загрузчик мог загрузить их с блочного устройства, даже несмотря на то, что окончательная работающая система не использует блочные устройства.Но загрузчик также может получить ядро ​​и архив cpio без использования блочного устройства, например, загрузившись по сети.

18
27.01.2020, 19:44

Теги

Похожие вопросы