Продолжаю серию статей про систему на кристалле в плате Марсоход2, которую мы создаем на базе opensource Amber ARM.
Конечно, хотелось бы получить от системы максимум возможного. «Идея-фикс» - это, конечно, запустить Linux в плате. К сожалению, я не являюсь таким уж большим специалистом в Linux, но отношусь к ней, как к «божеству», считая ее одним из важнейших достижений человечества .
Ну хоть какую нибудь версию, пусть не самую последнюю, запустить бы!
В принципе, кажется, это не должно быть большой проблемой. Ведь автор AMBER SoC успешно запускал версию ядра 2.4.27. В исходниках проекта AMBER есть папка sw/vmlinux, в которой есть следующие файлы:
- README.txt – описание метода загрузки ядра в систему и инструкция по самостоятельной компиляции ядра.
- vmlinux – скомпилированное ядро Линукс, файл типа elf, готовый к загрузке в систему.
- vmlinux.dis.bz2 – архив дизассембированного ядра Линукс.
- vmlinux.mem.bz2 – архив текстового файла, описывающего содержимое vmlinux в виде «адрес-слово». Этот файл может понадобиться для симуляции работы Линукс в Verilog симуляторе.
- initrd-200k-hello-world – простейший образ Initial Ram Disk, этот диск может монтироваться после загрузки ядра и затем с этого диска должна запуститься программа hello-world.
- initrd-200k-dhry – другой образ Initial Ram Disk
- patch-2.4.27-vrs1.bz2 – патч для ядра Линукс от компании ARM. Нужен для самостоятельной сборки ядра.
- patch-2.4.27-amber2.bz2 – патч AMBER SoC, так же нужен в случае самостоятельной сборки ядра.
Итак, читаю инструкцию README.txt и пытаюсь ее выполнить.
У нас уже есть проект для FPGA Cyclone III платы Марсоход2, который реализует SoC. Вы можете его взять, например на GitHub, вот этот TAG: https://github.com/marsohod4you/Amber-Marsohod2/archive/sdram-attached.zip
Тут полностью проект для среды Altera Quartus II для нашей платы Марсоход2.
После старта системы из внутренней BOOTROM сперва запускается монитор, который позволяет писать в ячейки памяти SDRAM, читать память, загружать образы в память системы через последовательный порт протоколом XMODEM-1K. Я этот монитор уже подробно описывал вот здесь.
Теперь, пользуясь этим монитором, нам нужно сперва загрузить командой «b» бинарный образ initrd в память, а потом загрузить командой «l» образ ядра Линукс – vmlinux.
Команда «l» загружает elf файл по адресу 0x80000. Туда же, по адресу 0x80000 нужно сделать переход для запуска образа. В мониторе для этого есть команда «j». То есть я буду набирать команду «j 80000».
Вот с образом initrd все не так просто.
Оригинальный проект AMBER выполненный для FPGA Xilinx и платы, содержащей 32Мб памяти. Я только пытаюсь портировать этот проект для Altera Cyclone III и для нашей платы Марсоход2. У меня есть только 8Мб памяти. При этом, в инструкции написано, что образ initrd нужно загрузить с 8-го мегабайта (которого у меня уже нет).
Что делать?
Я посмотрел как запускается Линукс. По идее, монитор (его исходный текст есть в папке проекта sw/boot-loader) создает некую структуру ATAG, описывающие различные параметры запуска: размер памяти, адрес initrd и прочее. Структура будет скопированна расположена по фиксированному адресу 0x7c00. Видимо ядро Linux знает, откуда брать эту таблицу.
Я решил, что я модифицирую ее нужным мне образом ну и все должно заработать.
Я делаю свой загрузчик, его исходники в папке sw/boot-loader-8M (на GitHub).
В нем в ассемблерном файле start.S вот такая таблица ATAG:
ATAGBase: .word ATAG_CORE_SIZE
.word ATAG_CORE
.word FLAG_READONLY @ flags
.word 4096 @ page size
.word 0x0 @ rootdev
.word ATAG_MEM_SIZE
.word ATAG_MEM
/* .word 32*1024*1024 @ size - 32MB */
.word 8*1024*1024 @ size - 8MB
.word 0x0 @ start
.word ATAG_RAMDISK_SIZE
.word ATAG_RAMDISK
.word 1 @ flags: bit 0 = load, bit 1 = prompt
.word 0x000000d0 @ size in 1k blocks
/* .word 0x00800000 @ physical address of start of ramdisk */
.word 0x00700000 @ physical address of start of ramdisk
.word ATAG_INITRD_SIZE
.word ATAG_INITRD
/* .word 0x02800000 @ virtual address of start of initrd image */
.word 0x02700000 @ virtual address of start of initrd image
.word 0x00032000 @ size = 200k
.word ATAG_NONE
.word 0x0
EndATAG: .word 0x0
Я объявляю, что у меня только 8Мб и что initrd будет с 7-го мегабайта. Бут лоадер уже откомпилирован и находится в FPGA в статической памяти.
Вот пробую. Я использую терминал последовательного порта TeraTerm, он умеет отправлять через ком-порт файлы по протоколу XMODEM:

Не работает. В принципе как-то стартует, но в конце концов виснет.
Во-первых, видно, что ядро не приняло мой параметр из таблицы ATAG про общий размер памяти 8Mb. Так и продолжает писать – в системе 32Мб. Это неверно и это плохо.
Во-вторых, не монтируется initrd. Это еще хуже.
Получается, что придется самому компилировать ядро Linux и разбираться почему все это происходит.
С другой стороны – может это и не плохо? Получу новый
Подробнее...