Decompressing linux parsing elf no relocation needed

#01 LinuxDay — Ошибка: Decompressing linux parsing elf done booting the kernel

В процессе изучения операционной системы linux которую мы сейчас планируем внедрить в офисе, а это Simple Linux (кто не знает это ветка и разработка от ООО «Базальт СПО» https://www.basealt.ru/ )

Кто следит за моим блогом знает, что у меня талант ломать системы (мне надо в тестировщиках работать) )

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

И после непродолжительного времени у меня виртуалка с Линуксом ушла в черный экран с ошибкой:

Текст ошибки:

Decompressing Linux parsing ELF done И
Booting the kernel
Spectre v2 : Spectre mitigation : kernel not compiled with retpoline; no mitigation available!
starting version 239
sd 0.0.0.0 [sda] Assuming drive cache: write through mount: /root/run filesystem was mounted, but any subsequent operation failed: No such file or directory.

После того как вылетела эта ошибка моя работа с линуксом была максимум час и руки чесались все переставить и не тратить время зря, но интерес разобраться с этим был велик, тем более как можно упустить такой момент, что бы глубже копнуть в линукс и багрепортинг.

В итоге начал с самого простого, что делают практически все админы, откатится на старую версию (я до этого события обновлял ядро) и была мысль, что после установки я не сделал перезагрузку что могло поломать операционку.

Linux — загрузку в режиме восстановления (Recovery mode)

Решил сделать загрузку в режиме восстановления, для этого перезагрузил систему и в окне меню загрузки необходимо выбрать пункт: Дополнительные параметры для simply Linux ***

далее в следующем списке у нас есть 4 варианта загрузки:

  1. обычный режим
  2. режим восстановления (recovery mode)
  3. предыдущая версия ядра
  4. прошла версия ядра

Загрузившись в режиме восстановления мне так же не получилось, потому как у меня система встряла на этапе загрузки hostname service, но это обходится легко, нажимаем ALT + F2 переходим в консоль, логинимся и вот мы в системе.

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

телеграмм чат с адресом alt_linux

Мне буквально на мой вопрос ответили в течение 5 минут и сказали, что у меня походу упали Иксы (графическая оболочка) и сказали, что бы посмотрел логи по следу пути:

и там увидел следующее:

и как тут можно увидеть что он подгружает драйвер Nvidia, но найти его не может.

Поэтому у меня и не загружался рабочий стол!! УРА. ))) Я сразу вспомнил, что когда бегал по настройкам поставил драйвер на видео Проприетарный от Nvidia и поэтому у меня когда в спящий режим ушла ос она уже не смогла вернуться обратно с рабочим столом!.

А теперь давайте расскажу как это исправить!

Ошибка: Decompressing linux parsing elf done booting the kernel

Для того что бы исправить ошибку Ошибка: Decompressing linux parsing elf done booting the kernel и что бы загрузился рабочий стол необходимо:

  1. загрузится в recovery mode ну или просто вызвать ALT + F2
  2. зайти в категорию /etc/X11/xorg.conf.d
  3. открыть на редактирование файл 10-monitor.conf
  4. закомментировать строчку # Driver «nvidia»

должно получится так:

# Generated by xsetup

Section «Monitor»
Identifier «Monitor0»
EndSection

Section «Device»
Identifier «Card0»
# Driver «nvidia»
EndSection

Section «Screen»
Identifier «Screen0»
Device «Card0»
Monitor «Monitor0»
SubSection «Display»
Modes «1600×900»
EndSubSection
EndSection

Вот и все! Первый день прошел удачно! начинаем отсчет: #01 LinuxDay

Источник

unixforum.org

Форум для пользователей UNIX-подобных систем

  • Темы без ответов
  • Активные темы
  • Поиск
  • Статус форума

Decompressing Linux… Parsing ELF… done (Booting the kernel. Loading, please wait…)

Decompressing Linux… Parsing ELF… done

Сообщение Rakomka » 22.06.2009 15:08

Читайте также:  Нет звука проигрыватель windows media для windows 10

Re: Decompressing Linux… Parsing ELF… done

Сообщение Rootlexx » 22.06.2009 16:02

Re: Decompressing Linux… Parsing ELF… done

Сообщение Rakomka » 22.06.2009 16:33

Re: Decompressing Linux… Parsing ELF… done

Сообщение Rakomka » 22.06.2009 17:07

Re: Decompressing Linux… Parsing ELF… done

Сообщение Rootlexx » 22.06.2009 18:32

Re: Decompressing Linux… Parsing ELF… done

Сообщение Rakomka » 22.06.2009 20:37

Re: Decompressing Linux… Parsing ELF… done

Сообщение Rootlexx » 23.06.2009 00:19

Re: Decompressing Linux… Parsing ELF… done

Сообщение Rakomka » 23.06.2009 14:57

Re: Decompressing Linux… Parsing ELF… done

Сообщение KernelPanic » 23.06.2009 16:27

Источник

[РЕШЕНО] Lenovo ThinkPad x120e не работает загрузчик

# 9 лет, 3 месяца назад (отредактировано 8 лет, 11 месяцев назад) У меня ноутбук Lenovo ThinkPad x120e с процессором AMD Zakate E350, а это насколько я понимаю x86-64. Скачал дуал дистрибутив с помощью dd под убунтой записал на флешку, и теперь у меня при загрузке и попытке запуска установки для x86-64 i686 пишется следующее:

И на этом все, мигает черта и ничего не происходит. С этой же флешки запускал установку на Samsung NC10 и на каком-то Asus Eee PC.
Что делать, неужели не видать арча моему буку?

при запуске установщика, жмем таб в меню с нужной архитектурой, и прописываем

Попробуйте образ x86-64. по отзывам линукс на этом девайсе заводится.
Может девайс не исправен?

Попробуйте поиграть с опциями ядра при загрузке (noapic).
Еще, там UEFI случайно нет?
Если да, тогда смотрите Wiki.

Спасибо, но там советы только по настройке системы, что делать, если система вообще не ставится там не написано) ,Но хотя бы теперь я уверен в том, что железки поддерживаются. Может при выборе варианта установки можно что-нибудь прописать? Попробуйте для чистоты эксперимента флешку меньше 4 Гб или записать образ сначала каким-нибудь ультра-исо.а затем поверх не форматируя unetbootin’ом. Сталкивался с похожей проблемой с разного рода дешевыми флешками и почему-то не на всех дистрибутивах. Причинно-следственные связи отследить не удалось, но указанный способ срабатывает. А на флешках меньше 4 гигов, все обычно сразу нормально. У меня от части похожая ситуация, тока не могу поставить на свой ПК, при установки x64-86 наглухо засыпает, разбудить помогает только ресет.
Из железа мать с EFI… грешил на него.. Хотя до этого арч спокойно ставился и работал (я тут его перед новым релизом удачно грохнул)
Ради эксперимента начал установку 32-х, пошло как по маслу (но 32 не подходит).
Пробовал менять флешки ставил и с 8-и и с 4-х гиговых, перезаписывал образ и dd и unibootin, в usb разные пихал и в 3-ю версию тоже. Перезакачивал образ с разных сайтов… и везде результат один и тотже при установке x86-64 уходит в нирвану….
Забыл сказать, на свой нетбук (s205) с обоих флешек установка проходит без проблем и 32-х и 64-х…..

Щас попробую в биосе ковырнуть и через исо-ульра записать… поже отпишусь.

RaZario
У меня от части похожая ситуация, тока не могу поставить на свой ПК, при установки x64-86 наглухо засыпает, разбудить помогает только ресет.
Из железа мать с EFI… грешил на него.. Хотя до этого арч спокойно ставился и работал (я тут его перед новым релизом удачно грохнул)
Ради эксперимента начал установку 32-х, пошло как по маслу (но 32 не подходит).
Пробовал менять флешки ставил и с 8-и и с 4-х гиговых, перезаписывал образ и dd и unibootin, в usb разные пихал и в 3-ю версию тоже. Перезакачивал образ с разных сайтов… и везде результат один и тотже при установке x86-64 уходит в нирвану….
Забыл сказать, на свой нетбук (s205) с обоих флешек установка проходит без проблем и 32-х и 64-х…..

Щас попробую в биосе ковырнуть и через исо-ульра записать… поже отпишусь.

Источник

Процесс загрузки ядра. Часть 5.

Декомпрессия ядра

Это пятая часть серии Процесса загрузки ядра . Мы видели переход в 64-битный режим в предыдущей части и в этой части мы продолжим с этого момента. Прежде чем мы перейдём к коду ядра, мы увидим последние шаги: подготовку к декомпрессии ядра, перемещение и, непосредственно, декомпрессию ядра. Итак. давайте снова погрузимся в код ядра.

Подготовка к декомпрессии ядра

Мы остановились прямо перед переходом к 64-битной точке входа — startup_64 , расположенной в arch/x86/boot/compressed/head_64.S. В предыдущей части мы уже видели переход к startup_64 в startup_32 :

Так как мы загрузили новую глобальную таблицу дескрипторов , и был переход CPU в другой режим (в нашем случае в 64-битный режим), мы можем видеть настройку сегментов данных в начале startup_64 :

Читайте также:  Dos windows server 2012

Все сегментные регистры, кроме регистра cs , теперь сброшены после того как мы перешли в long mode .

Следующий шаг — вычисление разницы между адресом, по которому скомпилировано ядро, и адресом, по которому оно было загружено:

rbp содержит начальный адрес распакованного ядра и после выполнения этого кода регистр rbx будет содержать адрес релокации ядра для декомпрессии. Такой код мы уже видели в startup_32 (вы можете прочитать об этом в предыдущей части — Расчёт адреса релокации), но нам снова нужно вычислить его, поскольку загрузчик может использовать 64-битный протокол загрузки и в этом случае startup_32 просто не будет выполнен.

На следующем шаге мы видим установку указателя стека, сброс регистра флагов и установку GDT заново из-за того, что в случае 64-битного протокола 32-битный сегмент кода может быть проигнорирован загрузчиком:

Если вы посмотрите на исходный код ядра Linux после команды lgdt gdt64(%rip) , вы увидите, что есть некоторый дополнительный код. Этот код необходим для включения пятиуровневой страничной организации, в случае необходимости. В этой книге мы рассмотрим только четырёхуровневую страничную организацию, поэтому этот код будет проигнорирован.

Как вы можете видеть выше, регистр rbx содержит начальный адрес кода декомпрессора ядра, и мы помещаем этот адрес со смещением boot_stack_end в регистр rsp , который представляет указатель на вершину стека. После этого шага стек будет корректным. Вы можете найти определение boot_stack_end в конце arch/x86/boot/compressed/head_64.S:

Он расположен в конце секции .bss , прямо перед таблицей .pgtable . Если вы посмотрите сценарий компоновщика arch/x86/boot/compressed/vmlinux.lds.S, вы найдёте определения .bss и .pgtable .

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

Прежде всего, мы помещаем rsi в стек. Нам нужно сохранить значение rsi , потому что теперь этот регистр хранит указатель на boot_params , которая является структурой режима реальных адресов, содержащая связанные с загрузкой данные (вы должны помнить эту структуру, мы заполняли её в начале кода настройки ядра). В конце этого кода мы снова восстановим указатель на boot_params в rsi .

Следующие две инструкции leaq вычисляют эффективные адреса rip и rbx со смещением _bss — 8 и помещают их в rsi и rdi . Зачем мы вычисляем эти адреса? На самом деле сжатый образ ядра находится между этим кодом копирования (от startup_32 до текущего кода) и кодом декомпрессии. Вы можете проверить это, посмотрев сценарий компоновщика — arch/x86/boot/compressed/vmlinux.lds.S:

Обратите внимание, что секция .head.text содержит startup_32 . Вы можете помнить это из предыдущей части:

Секция .text содержит код декомпрессии:

.rodata..compressed содержит сжатый образ ядра. Таким образом, rsi будет содержать абсолютный адрес _bss — 8 , а rdi будет содержать относительный адрес релокации _bss — 8 . Когда мы сохраняем эти адреса в регистрах, мы помещаем адрес _bss в регистр rcx . Как вы можете видеть в скрипте компоновщика vmlinux.lds.S , он находится в конце всех секций с кодом настройки/ядра. Теперь мы можем начать копирование данных из rsi в rdi по 8 байт с помощью инструкции movsq .

Обратите внимание на инструкцию std перед копированием данных: она устанавливает флаг DF , означающий, что rsi и rdi будут уменьшаться. Другими словами, мы будем копировать байты задом наперёд. В конце мы очищаем флаг DF с помощью инструкции cld и восстанавливаем структуру boot_params в rsi .

После релокации мы имеем адрес секции .text и совершаем переход по нему:

Последняя подготовка перед декомпрессией ядра

В предыдущем абзаце мы видели, что секция .text начинается с метки relocated . Первое, что она делает — очищает секцию bss :

Нам нужно инициализировать секцию .bss , потому что скоро мы перейдём к коду на C. Здесь мы просто очищаем eax , помещаем адрес _bss в rdi и _ebss в rcx , и заполняем его нулями с помощью инструкции rep stosq .

В конце мы видим вызов функции extract_kernel :

Мы снова устанавливаем rdi в указатель на структуру boot_params и сохраняем его в стек. В то же время мы устанавливаем rsi для указания на область, которая должа использоваться для распаковки ядра. Последним шагом является подготовка параметров extract_kernel и вызов этой функции для распаковки ядра. Функция extract_kernel определена в arch/x86/boot/compressed/misc.c и принимает шесть аргументов:

  • rmode — указатель на структуру boot_params, которая заполнена загрузчиком или во время ранней инициализации ядра;
  • heap — указатель на boot_heap , представляющий собой начальный адрес ранней загрузочной кучи;
  • input_data — указатель на начало сжатого ядра или, другими словами, указатель на arch/x86/boot/compressed/vmlinux.bin.bz2 ;
  • input_len — размер сжатого ядра;
  • output — начальный адрес будущего распакованного ядра;
  • output_len — размер распакованного ядра;
Читайте также:  Темы для часов для windows

Все аргументы буду передаваться через регистры согласно двоичному интерфейсу приложений System V (ABI). Мы закончили подготовку и переходим к декомпрессии ядра.

Декомпрессия ядра

Как мы видели в предыдущем абзаце, функция extract_kernel определена arch/x86/boot/compressed/misc.c и содержит шесть аргументов. Эта функция начинается с инициализации видео/консоли, которую мы уже видели в предыдущих частях. Нам нужно сделать это ещё раз, потому что мы не знаем, находились ли мы в режиме реальных адресов, использовался ли загрузчик, или загрузчик использовал 32 или 64-битный протокол загрузки.

После первых шагов инициализации мы сохраняем указатели на начало и конец свободной памяти:

где heap является вторым параметром функции extract_kernel , который мы получили в arch/x86/boot/compressed/head_64.S:

Как вы видели выше, boot_heap определён как:

где BOOT_HEAP_SIZE — это макрос, который раскрывается в 0x10000 ( 0x400000 в случае bzip2 ядра) и представляет собой размер кучи.

После инициализации указателей кучи, следующий шаг — вызов функции choose_random_location из arch/x86/boot/compressed/kaslr.c. Как можно догадаться из названия функции, она выбирает ячейку памяти, в которой будет разархивирован образ ядра. Может показаться странным, что нам нужно найти или даже выбрать место для декомпрессии сжатого образа ядра, но ядро Linux поддерживает технологию kASLR, которая позволяет загрузить распакованное ядро по случайному адресу из соображений безопасности.

Мы не будем рассматривать рандомизацию адреса загрузки ядра Linux в этой части, но сделаем это в следующей части.

Теперь мы вернёмся к misc.c. После получения адреса для образа ядра мы должны были совершить некоторые проверки и убедиться в том, что полученный случайный адрес правильно выровнен и является корректным:

После этого мы увидим знакомое сообщение:

и вызываем функцию __decompress :

которая будет распаковывать ядро. Реализация функции __decompress зависит от того, какой алгоритм декомпрессии был выбран во время компиляции:

После того как ядро распаковано, остаются две последние функции — parse_elf и handle_relocations . Основное назначение этих функций — переместить распакованный образ ядра в правильное место памяти. Дело в том, что декомпрессор распаковывает на месте, и нам всё равно нужно переместить ядро на правильный адрес. Как мы уже знаем, образ ядра является исполняемым файлом ELF, поэтому главной целью функции parse_elf является перемещение загружаемых сегментов на правильный адрес. Мы можем видеть загружаемые сегменты в выводе программы readelf :

Цель функции parse_elf — загрузить эти сегменты по адресу output , который мы получили с помощью функции choose_random_location . Эта функция начинается с проверки сигнатуры ELF:

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

С этого момента все загружаемые сегменты находятся в правильном месте.

Следующим шагом после функции parse_elf является вызов функции handle_relocations . Реализация этой функции зависит от опции конфигурации ядра CONFIG_X86_NEED_RELOCS , и если она включена, то эта функция корректирует адреса в образе ядра и вызывается только в том случае, если во время конфигурации ядра была включена опция конфигурации CONFIG_RANDOMIZE_BASE . Реализация функции handle_relocations достаточно проста. Эта функция вычитает значение LOAD_PHYSICAL_ADDR из значения базового адреса загрузки ядра и, таким образом, мы получаем разницу между тем, где ядро было слинковано для загрузки и тем, где оно было фактически загружено. После этого мы можем выполнить релокацию ядра, поскольку мы знаем фактический адрес, по которому было загружено ядро, адрес по которому оно было слинковано для запуска и таблицу релокации, которая находится в конце образа ядра.

После перемещения ядра мы возвращаемся из extract_kernel обратно в arch/x86/boot/compressed/head_64.S.

Адрес ядра находится в регистре rax и мы совершаем переход по нему:

На этом всё. Теперь мы в ядре!

Заключение

Это конец пятой части процесса загрузки ядра Linux. Мы больше не увидим статей о загрузке ядра (возможны обновления этой и предыдущих статей), но будет много статей о других внутренних компонентах ядра.

В следующей главе будут описаны более подробные сведения о процессе загрузки ядра Linux, например рандомизация адреса загрузки и т.д.

От переводчика: пожалуйста, имейте в виду, что английский — не мой родной язык, и я очень извиняюсь за возможные неудобства. Если вы найдёте какие-либо ошибки или неточности в переводе, пожалуйста, пришлите pull request в linux-insides-ru.

Источник

Оцените статью