Ограничения размера initramfs на ARM?

Я создаю загрузочную систему Linux на плате PicoZed (ядро ARM CortexA9), и я столкнулся с "ограничением", которое, на мой взгляд, не является ограничением (мне кажется, что это еще одна проблема, маскирующаяся под ограничение).

Я загружаюсь, запуская систему в режиме загрузки JTAG; после включения платы я использую отладчик xmd для загрузки u-boot в оперативную память системы, а затем запускаю ее.

Затем я помещаю ядро ​​(uImage), образ gzip'd initramfs и дерево устройств в память. Наконец, я говорю u-boot, чтобы загрузить систему, используя bootm и используя три аргумента, чтобы указать места в памяти всех образов.

Все это работает, и мне удается загрузить Linux + userland. Тем не менее, мне нужно вырастить initramfs, и именно здесь я сталкиваюсь с проблемами.

Рабочее изображение точно 16MiB. Я попытался сделать это 24MiB (полностью обновляется с нуля каждый раз, когда я пытаюсь загрузиться), но только после того, как ядро ​​загрузилось и оно пытается найти init, ядро ​​сообщает об ошибках файловой системы и дает сбой. Там не должно быть никаких совпадений, но на всякий случай я попытался немного переместить вещи, но возникла та же проблема.

После поиска некоторых советов я видел, как кто-то на форуме сказал, что изображение должно быть размещено с выравниванием 16 МБ (что я не думаю, что это правда, но я попробовал его, тем не менее, но это не получилось система). В другом посте утверждалось, что изображения должны быть выровнены по размерам (что я опять не считаю верным, но я тоже это попробовал, но без изменений). Еще в одном посте утверждается, что это происходит, если образ initramfs пересекает границу конца __init, и что размещение изображения initramfs внутри него позволит восстановить память после того, как изображение было распаковано ядром, а размещение за пределами раздела __init приведет к работать, но затем эта память навсегда теряется после загрузки. Я слишком мало знаю о Linux, чтобы знать, является ли что-либо из этого правдивым / точным, и я понятия не имею, где "__init" - если такая вещь существует - конечная граница есть, но если проблема в том, что я пересекал его, я пытался переместить изображение initramfs далеко за пределы того места, где я ранее его использовал, но это ничего не изменило.

Я также попробовал исходное местоположение (которое работает с изображением размером 16 МБ) и создал изображение размером 16 МБ + 1 КБ, но это тоже не сработало. (Очевидно, что он не перекрывает ни одно из перезаписываемых изображений).

Первоначально это привело меня к мысли, что где-то скрывается ограничение размера initramfs в 16 МБ. Но при поиске я подумал, что это не имеет смысла - насколько я могу собрать команду bootm в u-boot, она должна настроить список тегов для системы (который включает в себя расположение и размер initramfs).), и я до сих пор не встречал никаких замечаний по поводу ограничения в 16 МБ по отношению к спискам тегов для initramfs.

Я нашел страницу, на которой утверждается, что размер initramfs на практике ограничен примерно половиной размера физической памяти в системе, а плата PicoZed имеет 1 ГБ ОЗУ, поэтому мы на несколько порядков от того, что "следует" быть ограничением.

Для пояснения: изображение размером 16 МБ - это размер необработанного изображения; сжатый это чуть менее 6MiB. Однако, если я заполняю его так, чтобы он не сжимался настолько плотно, это не имеет никакого значения - проблема, похоже, не связана с размером сжатого изображения, только с несжатым изображением.

Главный вопрос:

  • Откуда этот очевидный предел размера initramfs в 16 МБ?

Боковой вопрос:

  • Существует ли такая вещь, как "раздел __init ядра", который восстанавливается ядром после распаковки / загрузки изображений? Если так, как я могу увидеть / настроить местоположение / размер этого?

2 ответа

Решение

Ограничения размера initramfs на ARM?

Я не сталкивался с ограничением размера 16 МБ, как вы утверждаете.
Когда-то я думал, что также существует ограничение по размеру, но это оказалось проблемой памяти во время загрузки. Как только это было решено, я использовал большие initramfs 30MiB (например, с библиотеками glibc, gtstreamer и qt5).

Откуда этот очевидный предел размера initramfs в 16 МБ?

Там нет ни одного. Ramfs ограничен только доступной оперативной памятью.
Существует определение для "размера RAM-диска по умолчанию", но это не повлияет на размер initramfs.


Ваш метод загрузки с помощью команды U-Boot bootm является подозрительным, т.е. вы передаете адрес памяти initramfs в качестве второго аргумента.
Документация U-Boot четко описывает второй аргумент как "адрес образа initrd " (выделение добавлено).
Там нет упоминания об initramfs в качестве аргумента.

В документации ядра Linux ясно говорится, что архив initramfs "связан с образом ядра Linux" и (в отличие от initrd) не является "отдельным файлом".

В ядре есть запись menuconfig для указания пути к cpio- файлу initramfs. Скрипт make добавит этот файл cpio к образу ядра, так что для загрузки будет единственный файл образа.

Так что может показаться, что вы на самом деле загружаетесь с initrd, но называете его initramfs.


Существует ли такая вещь, как "раздел __init ядра", который восстанавливается ядром после распаковки / загрузки изображений?

Да, есть раздел памяти __init, который освобождается после завершения инициализации ядра.

Если так, как я могу увидеть / настроить местоположение / размер этого?

Обычно подпрограммы и данные, которые не используются после инициализации, могут быть объявлены с помощью __init макро. Смотрите это.
Расположение и размер этого раздела памяти будет зависеть от сценария компоновщика, а не от явного пользовательского контроля. Файл ядра System.map должен содержать информацию для просмотра.

Я думаю, вам нужно передать ramdisk_size в команду uboot bootargs

ramdisk_size должен быть установлен, если размер распакованного файла на ram-диске больше установленного по умолчанию. Это должно быть больше, чем размер распакованного файла.

Другие вопросы по тегам