commit - 9472018638dac9837b3f82455425865d2f163729
commit + 0241a7fc9bbeab66b38dd65de218e221b91d7b28
blob - /dev/null
blob + adbbd86e4d5b64c9799faab2bba7153ece053b19 (mode 644)
--- /dev/null
+++ reports/20230302-v0.0.1.md
+squⱯt v0.0.1
+============
+
+С++11 код, запускаемый на aarch64 железе.
+
+Структура проекта
+-----------------
+
+Код проекта расположен в следующих исходных файлах:
+* `boot.S`: стартовый (загрузочный) код в виде ассемблерного листинга.
+ Код загоняет в бесконечный цикл все процессоры, кроме _первого_ (используя
+ для идентификации регистр [MPIDR\_EL1][s0]). А на первом
+ процессоре обнуляет секцию `BSS`, настраивает стек на адрес точки входа и
+ отдает управление в C++ функцию `kernel_entry_point`. Стек по мере наполнения
+ растет в сторону уменьшения адреса, поэтому стартовые код (точки входа) не
+ перетирается.
+* `kernel.cc`: модуль _условного ядра_.
+ Вызывает необходимую инициализацию (на текущий момент это только UART) и
+ передает управление коду полезной нагрузки (на текущий момент это
+ `UART echo test mode`: получение из UART символов и их обратная отсылка).
+* `uart_virt.cc`: реализация работы UART([PL011][s1]) для платформы [virt в QEMU][s2].
+* `linker.ld`: описание геометрии секций для компоновщика.
+
+Проект собирается и запускается с использованием простого `Makefile`.
+
+[s0]: https://developer.arm.com/documentation/ddi0595/2021-12/AArch64-Registers/MPIDR-EL1--Multiprocessor-Affinity-Register "MPIDR_EL1, Multiprocessor Affinity Register"
+[s1]: https://developer.arm.com/documentation/ddi0183 "PrimeCell UART (PL011) Technical Reference Manual"
+[s2]: https://qemu.readthedocs.io/en/latest/system/arm/virt.html "QEMU: ‘virt’ generic virtual platform"
+
+
+Конфигурирование сборки
+-----------------------
+
+Для сборки используются утилиты из состава LLVM.
+Для учета локальных особенностей системы, где происходит сборка, используется файл `config.mk`.
+
+Сборка и запуск протестированы в двух arm64-конфигурациях:
+* Alpine Linux v3.17
+ Из особенностей тут только то, что используется утилита `objcopy` из пакета
+ `llvm14`.
+```
+$ cat config.mk
+OBJCOPY = llvm14-objcopy
+```
+
+* OpenBSD 7.2
+ Локальный конфиг нужен для явного использования инструментария LLVM из
+ пакетов, так как встроенный в базу не умеет кросс-компилировать.
+```
+$ cat config.mk
+(!) TBD
+```
+
+Сборка (команда `make`) последовательно вызовет следующие утилиты:
+* `${AC}` (по умолчанию `clang`): обработка ассемблерного файла (`.S`) для
+ получения объектного (`.o`).
+* `${CXX}` (по умолчанию `clang++`): обработка C++ файлов (`.cc`) для получения
+ объектных (`.o`).
+* `${LD}` (по умолчанию `ld.lld`): компоновка исполняемого (`.elf`) файла из
+ полученных на предыдущих шагах объектных файлов.
+* `${OBJCOPY}` (по умолчанию `llvm-objcopy`): дамп исполняемого файла в
+ _плоское_ представление его в памяти, как если бы этот файл был загружен на
+ исполнение. Результатом получает `.img` файл.
+
+
+Просмотр содержимого собранных бинарных файлов
+----------------------------------------------
+
+Утилиту `llvm-objdump` можно использовать для инспектирования содержимого
+получившегося `.elf` файла:
+```
+$ llvm-objdump -d squat.elf
+squat.elf: file format elf64-littleaarch64
+
+Disassembly of section .text.boot:
+
+0000000000000000 <_start>:
+ 0: a0 00 38 d5 mrs x0, MPIDR_EL1
+ 4: 00 5c 40 92 and x0, x0, #0xffffff
+ 8: 60 00 00 b4 cbz x0, 0x14 <_first_processor>
+
+000000000000000c <_idle>:
+ c: 5f 20 03 d5 wfe
+ 10: ff ff ff 17 b 0xc <_idle>
+
+0000000000000014 <_first_processor>:
+ 14: 60 14 00 10 adr x0, #652
+ 18: 41 14 00 10 adr x1, #648
+
+000000000000001c <_zero_bss>:
+ 1c: 1f 84 00 f8 str xzr, [x0], #8
+ 20: 1f 00 01 eb cmp x0, x1
+ 24: cb ff ff 54 b.lt 0x1c <_zero_bss>
+ 28: c0 fe ff 10 adr x0, #-40
+ 2c: 1f 00 00 91 mov sp, x0
+ 30: 02 00 00 94 bl 0x38 <kernel_entry_point>
+ 34: f6 ff ff 17 b 0xc <_idle>
+
+Disassembly of section .text:
+
+0000000000000038 <kernel_entry_point>:
+ 38: fd 7b bf a9 stp x29, x30, [sp, #-16]!
+ 3c: fd 03 00 91 mov x29, sp
+ 40: 25 00 00 94 bl 0xd4 <_ZN5Board4Uart10initializeEv>
+ 44: 1f 20 03 d5 nop
+ 48: a0 10 00 10 adr x0, #532
+ 4c: 04 00 00 94 bl 0x5c <_ZN12_GLOBAL__N_116uart_send_stringEPKc>
+ 50: 18 00 00 94 bl 0xb0 <_ZN12_GLOBAL__N_119uart_echo_test_modeEv>
+ 54: fd 7b c1 a8 ldp x29, x30, [sp], #16
+ 58: c0 03 5f d6 ret
+```
+Тут стоит заполнить, что первая инструкция, которая ожидается к исполнению
+`mrs x0, MPIDR_EL1` имеет байт код `a0 00 38 d5`.
+
+А результирующий _плоский_ `.img` файл можно смотреть с использованием
+классического `hexdump`:
+```
+$ hexdump -C squat.img
+00000000 a0 00 38 d5 00 5c 40 92 60 00 00 b4 5f 20 03 d5 |..8..\@.`..._ ..|
+00000010 ff ff ff 17 60 14 00 10 41 14 00 10 1f 84 00 f8 |....`...A.......|
+00000020 1f 00 01 eb cb ff ff 54 c0 fe ff 10 1f 00 00 91 |.......T........|
+00000030 02 00 00 94 f6 ff ff 17 fd 7b bf a9 fd 03 00 91 |.........{......|
+```
+Тут стоит снова заметить, что в начале дампа мы снова видим заветный байт код
+`a0 00 38 d5`, то есть нашу инструкцию `mrs x0, MPIDR_EL1`. Это минимальный
+признак того, что сборка прошла успешно.
+
+Запуск и текущая полезная нагрузка
+----------------------------------
+
+`make qemu`
+
+UART Echo test
+
+
+Запуск под отладкой
+-------------------
+
+`make gdb-remote`
+
+