commit - 730f64c68a1b81e1ef81f6f87362e64e60ddefc9
commit + 6b6a9b6f372bb83e8dee9a0b688c5f545ea4c0f1
blob - fb90d1c31e85e2279c21f1997b0773837c0030e3 (mode 644)
blob + /dev/null
--- reports/20230302-v0.0.1.md
+++ /dev/null
-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][c0].
-Для учета локальных особенностей системы, где происходит сборка, используется файл `config.mk`.
-
-Сборка и запуск протестированы в двух arm64-конфигурациях:
-* Alpine Linux v3.17
- Из особенностей тут только то, что используется утилита `objcopy` из пакета
- `llvm14`.
-```
-$ cat config.mk
-OBJCOPY = llvm14-objcopy
-```
-
-* OpenBSD 7.2
- Локальный конфиг нужен для явного использования инструментария LLVM из
- пакетов, так как встроенный в базу не умеет кросс-компилировать.
-```
-$ cat config.mk
-AS = /usr/local/bin/clang
-CXX = /usr/local/bin/clang++
-LD = /usr/local/bin/ld.lld
-OBJCOPY = /usr/local/bin/llvm-objcopy
-```
-
-Сборка (команда `make`) последовательно вызовет следующие утилиты:
-* `${AC}` (по умолчанию `clang`): обработка ассемблерного файла (`.S`) для
- получения объектного (`.o`).
-* `${CXX}` (по умолчанию `clang++`): обработка C++ файлов (`.cc`) для получения
- объектных (`.o`).
-* `${LD}` (по умолчанию `ld.lld`): компоновка исполняемого (`.elf`) файла из
- полученных на предыдущих шагах объектных файлов.
-* `${OBJCOPY}` (по умолчанию `llvm-objcopy`): дамп исполняемого файла в
- _плоское_ представление, как если бы этот файл был загружен в память на
- исполнение. Результатом получает `.img` файл.
-
-[c0]: https://llvm.org/ "The LLVM Compiler Infrastructure"
-
-Просмотр содержимого собранных бинарных файлов
-----------------------------------------------
-
-Утилиту `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`:
-```
-$ make qemu
-qemu-system-aarch64 -M virt -cpu cortex-a53 -kernel squat.img -nographic -monitor none -serial stdio
-Squat entry point
-UART echo test mode
->
-```
-
-В таком режиме код ждет получения очередного символа через UART, а затем
-отсылает его же обратно.
-
-
-Запуск под отладкой
--------------------
-
-При необходимости можно запустить QEMU в режиме отладки командой
-`make gdb-remote`. В отличии от обычного запуска (`make qemu`) при запуске qemu
-добавляются аргументы `-s -S`, которые включают отладку и ждут подключения
-отладчика. В нашем случае отладчиком будем выступать `lldb`, который локально
-подключится к QEMU через порт `1234`:
-```
-$ lldb
-(lldb) gdb-remote 1234
-```