[Перевод] Загружаем последнее ядро Linux с дискеты на 486-м компьютере
Ещё в августе 2019 года я проводил конкурс Sing-Along Week по синхронизации MIDI-файла с речевым синтезатором, который поёт песню. На своём складе я нашел MIDI-карту MQX-32M (клон Roland MPU-401), которую хотел использовать для преобразования MIDI-сигналов в интерфейс Apple II+ с синтезатором речи Echo II, но в конечном итоге использовал ноутбук с интерфейсом USB MIDI. Другой конкурс Pizza Week сподвиг меня заинтересоваться поиском компьютера 486, который бы поместился в коробку для пиццы, и вот предоставился подходящий случай.
Поиск на eBay был нелёгким, потому что не удавалось подобрать действительно хороший поисковый запрос. Я не стал утруждаться сохранением поиска, так как этот проект не приоритетный. Вместо этого время от времени что-то вдохновляло меня зайти на eBay и попробовать новые поисковые запросы. Пару недель назад я заметил этот 486-й компьютер и сделал предположение о размере корпуса, судя по высоте 5,25-дюймового отсека. Он довольно тонкий, и у него есть специальная карта, чтобы вставлять другие карты боком, а корпус короче, чем карта ISA. Хотя он и толще коробки для пиццы, но уже близко!
Материнская плата TMC PAT48PG4 поставляется с 32 МБ оперативной памяти (технически 36 МБ, в ней четыре 30-контактных SIM) и четырьмя картами: VGA, SoundBlaster, модем и многофункциональный I/O. Продавец проверил компьютер и продавал его как нерабочий, поскольку тот не проходил POST, хотя все карты работали. Мне в основном был нужен корпус, так что я особо не беспокоился. Конечно, когда я получил комп, нужно было проверить, действительно ли материнская плата мертва. У меня он тоже не заработал, но потом я обнаружил, что если нажать кнопку сброса, раздаётся несколько звуковых сигналов ошибки. Я попробовал другой источник питания, и систем ожила после нажатия кнопки Reset! Он все ещё не загружается из холодного выключения по нажатию кнопки питания, не уверен, там плохая крышка или небольшое повреждение батарейки (батарейка менялась раньше) мешает отключению линии Reset после включения питания. Тем не менее, он работал достаточно для того, чтобы исследовать его возможности.
Моя конечная цель — установить самый последний дистрибутив Linux и Python 3 на «большой» жёсткий диск. Поскольку у нас 486-й компьютер, установка текущего дистрибутива Linux — нетривиальная задача. Единственные дистрибутивы Linux, которые ещё поддерживают установку с дискет, довольно устарели. Обычно я полностью обходил установку с дискет и просто загружал старый компьютер через PXE, а затем устанавливал систему по сети. Я думал, что могу записать iPXE на дискету и вставить в ISA NIC, но iPXE просто зависает без каких-либо сообщений об ошибках сразу после загрузки с дискеты.
BIOS древний и мучается с поддержкой «большого» жёсткого диска, который я подключил. Размер диска 8,45 ГБ, но BIOS видит только 8,0 ГБ. Включение LBA в BIOS приводит к зависанию компьютера во время POST после обнаружения диска. Win98 fdisk настаивает, что диск всего 504 МБ. FreeDOS вообще его не видит. Я попробовал вставить в гнездо сетевой адаптер с XTIDE ROM, и XTIDE также настаивает на том, что диск не подключен.
Поскольку я хотел посмотреть, как Linux определит диск, мне нужно было найти способ загрузки Linux. Немного погуглив, я обнаружил опцию make tinyconfig, которая делает очень маленькое (но бесполезное) ядро, достаточно маленькое, чтобы поместиться на дискете. Я включил пару других опций, нашёл достаточно маленький initramfs и смог загрузить его на 486-й. Как и ожидалось, Linux без проблем видит диск и его полную ёмкость.
Следующий шаг — это фактически установить Linux на жёсткий диск. Я бы предпочёл не выпускать собственный дистрибутив, но, возможно, придётся это сделать. Другая возможность — загрузить Linux с дискеты, а затем загрузить ядро и initrd из текущего дистрибутива и kexec к нему. Но мне кажется, что это всё равно что заново изобрести iPXE.
Компиляция ядра Linux из исходного кода
Краткое изложение шагов по созданию образа на флоппи:
- git clone git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
- v5.8-rc2–1-g625d3449788f на время написания статьи
- make ARCH=x86 tinyconfig
- make ARCH=x86 menuconfig
- Установить процессор на 486: CONFIG_M486=y
- Processor type and features > Processor family > 486
- Включить tty: CONFIG_TTY=y
- Device Drivers > Character devices > Enable TTY
- Включить printk: CONFIG_PRINTK=y
- General Setup > Configure standard kernel features (expert users) > Enable support for printk
- Включить initramfs: CONFIG_INITRAMFS_COMPRESSION_GZIP=y
- General Setup > Initial RAM filesystem and RAM disk (initramfs/initrd) support > Support initial ramdisk/ramfs compressed using gzip
- Включить ELF: CONFIG_BINFMT_ELF=y
- Executable file formats > Kernel support for ELF binaries
- Установить процессор на 486: CONFIG_M486=y
- make ARCH=x86 bzImage
Вам понадобится rootfs, возьмите образ system-image-486 from Aboriginal Linux, извлеките rootfs.cpio.gz.
Тестовая загрузка с qemu:
qemu-system-i386 -kernel arch/x86/boot/bzImage -initrd ../system-image-486/rootfs.cpio.gz
Создание пустого образа флоппи:
dd if=/dev/zero of=linux-boot.img bs=1k count=1440
mkdosfs linux-boot.img
syslinux --install linux-boot.img
mount -o loop linux-boot.img /mnt
cp arch/x86/boot/bzImage /mnt
cp rootfs.cpio.gz /mnt
Создание /mnt/syslinux.cfg:
DEFAULT linux
LABEL linux
SAY Now booting the kernel from SYSLINUX...
KERNEL bzImage
APPEND initrd=rootfs.cpio.gz
Запись образа на дискету:
umount /mnt
fdformat /dev/fd0
ddrescue -f -D linux-boot.img /dev/fd0