Просмотр полной версии : Программирование голого железа Raspberry Pi
CityAceE
17.08.2023, 17:48
Я уже затрагивал тему программирования голого железа (bare metal). Заметку на эту тему (https://zx-pk.ru/content/500-Bare-metal-vybor-nastoiashchego-retrokompiutershchika) опубликовал здесь же на форуме. Сейчас решил вернуться к этой теме. Но понял, что она слишком обширна и, наверное, не до конца отвечает тематике нашего форума. В общем, в этой теме буду по мере появления у меня настроения потихоньку публиковать материалы по теме, а также отвечать на вопросы, если таковые возникнут.
Начну с того, без чего невозможно стартануть, чтобы запустить свой код на голом железе. Необходимо понимать как организован процесс загрузки Raspberry Pi. В какой файл нужно поместить свой код, с какого адреса скомпилировать и т.д. Вот ссылка на заметку Как загружается Raspberry Pi (https://blog.reext.ru/kak-zagruzhaetsya-raspberry-pi/). Не стал публиковать эту информацию на форуме, чтобы не засорять его непрофильной информацией.
CityAceE
18.08.2023, 11:21
Чтобы сделать первый шаг в программировании голого железа, неплохо бы понимать, а что можно реализовать с помощью такого подхода. За одно нелишним будет понимать, что из такого софта уже существует.
Для этого я подготовил небольшой обзор, который даст представление о bare metal софте под Raspberry Pi.
В обзоре есть упоминание эмулятора Спектрума. Также обратите внимание на демку Pi on Fire, в которой звуковое сопровождение написано под два AY.
Обзор bare metal программ для Raspberry Pi (https://blog.reext.ru/obzor-bare-metal-programm-dlya-raspberry-pi/)
P.S.В этой заметке я написал, что полноценного эмулятора Raspberry Pi не существует, но на самом деле эмулировать Raspberry Pi можно, но с некоторыми оговорками. Об этом я расскажу чуть позже.
Вот пример bare metal игры, написанной на чистом ассемблере:
https://www.youtube.com/watch?v=cFWNbK_dK0g
CityAceE
23.08.2023, 12:21
В обзор (https://blog.reext.ru/obzor-bare-metal-programm-dlya-raspberry-pi/) добавил информацию об ещё одном эмуляторе ZX Spectrum - πBacteria. Эмулятор написан на ассемблере, а исходники доступны.
https://www.youtube.com/watch?v=QkasVkToxNU
CityAceE
23.08.2023, 21:51
Для тех, кто хотел бы сделать первый шаг и, возможно, немного поэкспериментировать, приведу последовательность действий, которые необходимо произвести, чтобы запустить простейшую программу на ассемблере на голом железе под эмулятором. Здесь я буду описывать процесс для Windows.
Итак, для начала скачайте и установить эмулятор QEMU. Последнюю сборку под Windows можно скачать отсюда: https://qemu.weilnetz.de/w64/
Также нам потребуется кросс-ассемблер FASMARM для Windows. Скачать его можно отсюда: https://arm.flatassembler.net/
Далее скопируйте текст программы в блокнот и сохраните в файл HelloWorld.s:
org 0x6001000
mov r0, 0x9000 ; Загружаем в регистр r0 адрес консоли 0x10009000, вначале младшую половину
movt r0, 0x1000 ; а потом старшую половину
adr r1,text ; Загружаем в регистр r1 адрес начала текста
mov r2,0 ; Обнуляем счётчик в регистре r2
loop:
ldrb r3,[r1,r2] ; Загружаем в регистр r3 код следующего символа надписи
str r3,[r0] ; Выводим в консоль код символа из регистра r3
add r2,1 ; Увеличиваем счётчик на единицу
cmp r3,10 ; Сравниваем код символа с кодом перевода строки
bne loop ; Переходим к следующему символу, если код символа не равен коду перевода
finish:
b finish ; В конце программы зацикливаем строку саму на себя
text:
db "Hello, World!", 10
Сам я лично вместо стандартного блокнота пользуюсь Notepad++ и подсветкой синтаксиса, которую сделал похожей на привычный мне PyCharm:
https://pic.maxiol.com/images2/1692816885.780858384.helloworld.png
Распакуйте архив с ассемблером. Оттуда понадобится только исполняемый (.exe) файл. И положите рядом с ним ваш HelloWorld.s. Теперь всё готово для компиляции! Открываем консоль, переходим в папку с ассемблером и нашим файлом, и подаём команду:
fasmarm HelloWorld.s
https://pic.maxiol.com/images2/1692817238.780858384.compile.png
На выходе получаем файл HelloWorld.bin объёмом 54 байта. Теперь осталось только его запустить под эмулятором. Для запуска подаём такую команду в консоли:
"c:\Program Files\qemu\qemu-system-arm.exe" -M vexpress-a9 -serial stdio -kernel HelloWorld.bin
И наслаждаемся результатом:
https://pic.maxiol.com/images2/1692817589.780858384.consolehw.png
Появились вопросы? Задавайте!
CityAceE
24.08.2023, 11:09
Итак, давайте потихоньку двигаться дальше. Предлагаю внести в пример из предыдущего сообщения небольшие изменения. А именно, после строки с директивой org добавить ещё три строки:
blx start
thumb
start:
То есть по итогу должно получиться вот так:
https://pic.maxiol.com/images2/1692864575.780858384.hellothumb.png
Так как мы что-то добавили в программу, то исполняемый код должен увеличиться на несколько байт. Давайте скомпилируем и проверим. И что мы видим? Исполняемый код стал объёмом 46 байт, то есть ещё короче чем был! А был, напомню, 54 байта.
Что же произошло? Давайте попробуем разобраться и дизассемблировать код обеих вариантов с помощью популярного дизассемблера IDA Pro.
Вот так выглядит код первоначального варианта (54 байта):
https://pic.maxiol.com/images2/1692864928.780858384.hello32.png
Всё совпадает с ассемблерным текстом! (На команду MOV R0 не обращайте внимания. По умолчанию IDA для простоты восприятия заменяет некоторые последовательности команд в метакоманды. Вот и здесь она заменила две команды загрузки регистра R0 по половинкам (MOV и MOVT) в одну длинную загрузку, которая на самом деле отсутствует в наборе команд процессоров ARM. Где-то в настройках IDA Pro это можно отключить и тогда всё будет отображаться, как есть.)
А вот так выглядит дизассемблер модифицированного варианта (46 байт):
https://pic.maxiol.com/images2/1692865018.780858384.hello16.png
И тоже всё совпадает, и даже дополнительная команда BLX появилась. Но при этом код стал короче!
А произошло следующее: директивой thumb мы дали команду ассемблеру все дальнейшие команды вместо стандартного 32-х битного режима ассемблировать в 16-битном режиме thumb. А, собственно, командой BLX мы дали понять процессору, что код, на который будет осуществлён дальнейший переход, будет исполняться в режиме thumb.
В режиме thumb все команды, в отличие от 32-х битного режима, кодируются только двумя байтами. В результате исполняемый код такой программы становится более компактным. И всё было бы отлично, если бы не кое-какие ограничения. И прежде всего это ограниченный набор команд - их всего лишь 36. Есть и другие ограничения, но сейчас не будем на них останавливаться.
Что касается меня, то режим thumb привлёк моё внимание именно ограниченным набором команд. Дело в том, что за долгую историю архитектуры ARM было выпущено несколько поколений процессоров. Для них было придумано большое количество команд, у каждой из которых есть свои особенности. Разобраться и изучить их все довольно проблематично. А здесь же мы имеем только 36 команд, с помощью которых можно запрограммировать практически любое действие. При этом, если вам когда-нибудь вдруг станет тесно в рамках thumb, вы всегда сможете перейти на 32-х битную систему команд без необходимости что-то менять в своём коде. Наверное, здесь можно привести аналогию с процессорами i8080 (КР580ВМ80А) и Z80. Если писать код для процессора i8080 (аналогия с thumb), то код будет работать и на i8080, и на Z80. Но если вам становится тесно, то вы можете начать использовать дополнительные регистры и команды процессора Z80 (аналогия с 32-х битным режимом ARM), но тогда уже потеряете совместимость с i8080.
В конце хочу привести полный список из 36 команд процессоров ARM в режиме thumb:
№
Мнемоника
Команда
Пример
Эквивалент кода ARM
1
ADC
Сложение с учетом переноса
ADC Rd, Rs
ADCS Rd, Rd, Rs
2
ADD
Сложение
ADD Rd, Rs, Rn
ADD Rd, Rs, Rn
3
AND
Логическое "И"
AND Rd, Rs
ANDS Rd, Rd, Rs
4
ASR
Арифметический сдвиг вправо
ASR Rd, Rs
MOVS Rd, Rd, ASR Rs
5
B
Безусловный переход
B label
B label
6
BCC
Переход по условию CC
BCC label
BCC label
7
BIC
Сброс битов (маскирование)
BIC Rd, Rs
BICS Rd, Rd, Rs
8
BL
Переход со ссылкой
BL label
BL label
9
BX
Переход и смена режима ядра
BX Hs
BX Hs
10
CMN
Сравнение с отрицанием
CMN Rd, Rs
CMN Rd, Rs
11
CMP
Сравнение
CMP Rd, #Offset8
CMP Rd, #Offset8
12
EOR
Исключающее "ИЛИ"
EOR Rd, Rs
EORS Rd, Rd, Rs
13
LDMIA
Групповая загрузка регистров
LDMIA Rb!, {Rlist}
LDMIA Rb!, {Rlist}
14
LDR
Загрузка целого слова
LDR Rd, [PC, #lmm]
LDR Rd, [PC, #lmm]
15
LDRB
Загрузка байта
LDRB Rd, [Rb, Ro]
LDRB Rd, [Rb, Ro]
16
LDRH
Загрузка полуслова
LDRH Rd, [Rb, #lmm]
LDRH Rd, [Rb, #lmm]
17
LSL
Логический сдвиг влево
LSL Rd, Rs, #Offset5
MOVS Rd, Rs, LSL #Offset5
18
LDRSB
Загрузка байта со знаком
LDRSB Rd, [Rb, Ro]
LDRSB Rd, [Rb, Ro]
19
LDRSH
Загрузка полуслова со знаком
LDRSH Rd, [Rb, Ro]
LDRSH Rd, [Rb, Ro]
20
LSR
Логический сдвиг вправо
LSR Rd, Rs
MOVS Rd, Rd, LSR Rs
21
MOV
Пересылка
MOV Rd, #Offset8
MOVS Rd, #Offset8
22
MUL
Умножение
MUL Rd, Rs
MULS Rd, Rs, Rd
23
MVN
Пересылка с инверсией
MVN Rd, Rs
MVNS Rd, Rs
24
NEG
Инверсия (побитовое "НЕ")
NEG Rd, Rs
RSBS Rd, Rs, #0
25
ORR
Логическое "ИЛИ"
ORR Rd, Rs
ORRS Rd, Rd, Rs
26
POP
Извлечение регистров из вершины стека
POP {Rlist}
LDMIA R13!, {Rlist}
27
PUSH
Размещение регистров в вершине стека
PUSH {Rlist}
STMDB R13!, {Rlist}
28
ROR
Циклический сдвиг вправо
ROR Rd, Rs
MOVS Rd, Rd, ROR Rs
29
SBC
Вычитание с переносом
SBC Rd, Rs
SBCS Rd, Rd, Rs
30
STMIA
Групповое сохранение регистров
STMIA Rb!, {Rlist}
STMIA Rb!, {Rlist}
31
STR
Сохранение целого слова
STR Rd, [Rb, Ro]
STR Rd, [Rb, Ro]
32
STRB
Сохранение байта
STRB Rd, [Rb, Ro]
STRB Rd, [Rb, Ro]
33
STRH
Сохранение полуслова
STRH Rd, [Rb, Ro]
STRH Rd, [Rb, Ro]
34
SWI
Программное прерывание
SWI Value8
SWI Value8
35
SUB
Вычитание
SUB Rd, Rs, Rn
SUBS Rd, Rs, Rn
36
TST
Побитовая проверка
TST Rd, Rs
TST Rd, Rs
Rs - Регистр-источник (Register source)
Rd - Регистр-приёмник (Register destination)
Ro - Отступ (Register offset)
Rn - Второй аргумент в арифметических операциях
Rlist - Список регистров
CityAceE
24.08.2023, 15:35
В предыдущем сообщении я привёл список команд, с помощью которых можно запрограммировать любую процедуру. Однако осталось кое-что, о чём следует иметь представление, прежде чем делать свои первые шаги в программирования на ассемблере ARM. И речь идёт о регистрах процессора.
В отличие от Спектрума тут всё довольно просто - у процессоров есть 16 регистров, которые обозначаются как r0-r15, а также два специальных регистра - CPSR и SPSR. Собственно, на этом всё :)
Но, на самом деле, как обычно, есть нюансы. Их много, но я остановлюсь лишь не некоторых из них.
Начнём с регистров общего назначения. Как уже было написано выше их всего 16. И все они 32-х битные, то есть каждый из них может хранить 4 байта, и, соответственно, процессор за одну команду может оперировать с таким объёмом данных. Однако не всеми регистрами Rxx вы можете распоряжаться, как заходите. Некоторые из них имеют специальное назначение, а некоторые и вовсе недоступны из режима Thumb.
Первые 8 регистров (r0-r7) - это регистры общего назначения, которые доступны из любого режима процессора, не важно Thumb (CODE16) это или ARM (CODE32). Пять следующих регистров (r8-r12) доступны только из режима ARM. Остаётся ещё три регистра, которые отведены под специальные задачи и помимо традиционного обозначения r13-r15 имеют псевдонимы.
r13 (SP) - это указатель стека, такой же как на ZX Spectrum, только разрядностью побольше.
r14 (LR) - это, так называемый, регистр связи. Он необходим, например, для вызова подпрограмм. На ZX Spectrum, когда мы вызываем подпрограмму по команде CALL, адрес возврата записывается на стек. В процессорах же АРМ всё происходит несколько иначе - адрес возврата записывается не на стек, а как раз в этот самый регистр связи. Причём, если вы потом из подпрограммы вызовете ещё одну подпрограмму, то адрес возврата затрёт предыдущий и из первой подпрограммы вы уже не сможете вернуться. Вот поэтому при вложенных подпрограммах необходимо самому заботится о сохранении регистра LR и его своевременном восстановлении.
r15 (PC) - это программный счётчик. Тут без особенностей, он такой же, как на Z80.
Вот так будет нагляднее:
https://pic.maxiol.com/images2/1692887716.780858384.armregisters.png
CPSR (Current Program Status Register) - это регистр, который хранит флаги, а также информацию для обработки прерывания.
SPSR (Saved Program Status Register) - этот регистр хранит копию CPSR при обработке прерывания. Опять же, для нас этот регистр пока неактуален, как и всё, что связано с прерываниями.
На прерываниях останавливаться не будем, а вот про флаги поговорить, безусловно, стоит. В общем-то почти все флаги нам знакомы по процессору Z80:
Q (Saturation) - насыщение/переполнение в DSP-операциях (для нас пока неактуально)
V (oVerflow) - переполнение (знаковое)
C (Carry) - перенос бита (беззнаковый)
Z (Zero) - нулевой результат (равенство)
N (Negative) - отрицательное значение (бит 31 установлен)
Именно благодаря флагам мы можем производить какие-то действия в программе, в зависимости от результата работы предыдущих команд. В таблице приведено обозначение условий:
Предикат
Отрицание
Флаги
Комментарий
EQ
NE
Z
==
CS / HS
CC / LO
C
>= (беззнаковое)
MI
PL
N
< 0
VS
VC
V
переполнение
HI
LS
zC
> (беззнаковое)
GE
LT
NV || nv
>= (знаковое)
GT
LE
NzV || nzv
> (знаковое)
AL
-
-
Безусловная команда
Как и в Z80, здесь есть команда условного перехода, в качестве суффикса которой как раз используются обозначения условий из таблицы. И мы в программе "Hello, World!" уже использовали условный переход:
cmp r3,10 ; Сравниваем код символа с кодом перевода строки
bne loop ; Переходим к следующему символу, если код символа не равен коду перевода
В первой строчке мы сравниваем содержимое регистра r3 с числом 10. А во второй команде, при условии BNE (branch if not equal - bne) мы переходим на метку loop. На Спектруме аналогом этой команды была бы команда jr nz,loop.
Любопытно, но по умолчанию почти все команды никак не затрагивают флаговый регистр. Вы можете до посинения вызывать команду SUB R1,1 и ожидать, что рано или поздно произойдёт обнуление регистра, сторожа его командой BEQ:
mov r1,100
loop:
sub r1,1
beq exit ; Данная команда никогда не сработает
b loop
exit:
Однако вас будет ожидать разочарование - команда BEQ никогда не сработает. А всё потому, что флаговый регистр не будет реагировать на результат команды SUB. И вот чтобы флаговый регистр всё-таки отреагировал, вам необходимо явно указать, что вам требуется реакция флагового регистра. Делается это довольно просто - суффиксом S. То есть вместо SUB, вам нужно использовать команду SUBS.
mov r1,100
loop:
subs r1,1
beq exit ; Команда сработает, когда в R1 будет 0
b loop
exit:
В качестве бонуса, суффикс S вы можете использовать даже в команде MOV. То есть вот такая команда BEQ вполне себе сработает после MOVS:
movs r1,0
beq label ; Данная команда сработает
Но и это еще не всё! Помимо команд условного перехода практически любая команда может быть исполнена по условию, заданному в суффиксе. Например, команда MOVEQ будет выполнена только, если результат предыдущей операции, влияющий на флаговый регистр, будет равен нулю:
movs r1,0
moveq r2,1 ; Команда сработает
movne r2,2 ; Команда не сработает
Правда, если вы дизассемблируете код вот с такими условными командами, то вы увидите, что компилятор добавил к ним одну или несколько команд IT, которые как раз позволяют процессору эти самые условия обрабатывать. То есть суффикс с условием транслируется в некоторую конструкцию команд IT. Это вас не должно никак беспокоить, если только вы не бьётесь за каждый байт исполняемого файла.
Думаю, что для начала этой информации о регистрах процессоров ARM вам будет достаточно.
CityAceE
25.08.2023, 16:27
Вывод в консоль фразы "Hello, World!" - это, конечно, хорошо, но малоинтересно. Гораздо интереснее что-то графическое, цветастое, с анимацией и чтобы ещё попроще было в коде. И такая штука у меня есть для вас! Крохотная демка под названием FreeFull. Размер исполняемого файла всего лишь 254 байта, но выглядит всё довольно эффектно!
https://pic.maxiol.com/images2/1692970267.3280329127.freefull2.png
Не поленитесь, скомпилируйте и запустите её самостоятельно! Сделать это можно по аналогии с упомянутым примером (https://zx-pk.ru/threads/35227-programmirovanie-gologo-zheleza-raspberry-pi.html?p=1184668&viewfull=1#post1184668) "Hello, Wolrd!".
>> Вот (https://io.netgarage.org/arm/freefull_02.asm) << прямая ссылка на исходный текст.
Изучить этот исходник будет довольно интересно. Несмотря на то, что там всего лишь 94 строки текста, вы сможете увидеть, например, как инициализируется графический экран и как затем на нём попиксельно формируется картинка.
Интересно, хоть один человек найдётся, который отважится на компиляцию и запуск? А то у меня складывается ощущение, что я тут всё это сам себе рассказываю ;)
CityAceE
26.08.2023, 18:28
Адаптировал демку из предыдущего сообщения к железу Raspberry Pi и запустил её на реальных Raspberry Pi Zero, 1 и 2:
https://youtu.be/XT2WUvBWvJc
CityAceE
27.08.2023, 11:54
Итак, двигаемся дальше. Буквы в терминале - хорошо, красивая картинка на экране - ещё лучше! Но хочется какого-то интерактива. И вот здесь не всё так просто, как хотелось бы. Но об этом чуть ниже. А пока предлагаю вам текст короткой программы, которая опрашивает клавиатуру и выводит в терминал код нажатой клавиши:
org 0x6001000
blx start
thumb
start:
; Опрашиваем клавиатуру
movw r0,0x6004 ; Keyboard Status Register
movt r0,0x1000
ldrb r1,[r0]
and r1,0x10
cmp r1,0x10
bne finish
movw r0,0x6008 ; Keyboard Data
movt r0,0x1000
ldrb r1,[r0]
and r1,0xff
; Преобразуем байт в ASCII-строку в HEX-представлении
adr r2,key_code+1
mov r3,2
mov r0,r1
hex_convert:
and r1,0xf
cmp r1,0xa
addcs r1,0x7
add r1,0x30
strb r1,[r2]
sub r2,1
lsr r1,r0,4
subs r3,1
bne hex_convert
; Выводим строку в консоль
movw r0,0x9000 ; Адрес консоли 0x10009000
movt r0,0x1000
ldrb r1,[key_code]
strb r1,[r0]
ldrb r1,[key_code+1]
strb r1,[r0]
ldrb r1,[key_code+2]
strb r1,[r0]
finish:
b start
key_code:
db "00 "
Результат работы программы:
https://pic.maxiol.com/images2/1693126628.780858384.keyboard.png
В эмулируемом компьютере клавиатура подключена с помощью MMIO (Memory-mapped I/O) контроллера PL050, порты которого смотрят прямо в память, а базовым является адрес 0x10006000:
Address
Type
Description
Base + 0x00
rw
Control register.
Base + 0x04
r
Status register.
Base + 0x08
rw
Received data (read)/ Data to be transmitted (write).
Base + 0x0c
rw
Clock divisor register.
Base + 0x10
r
Interrupt status register.
А это значения битов статусного регистра:
Bits
Name
Description
0
KMID
This bit reflects the status of the KMIDATAIN line after synchronizing.
1
KMIC
This bit reflects the status of the KMICLKIN line after synchronizing and sampling.
2
RXPARITY
This bit reflects the parity bit for the last received data byte (odd parity).
3
RXBUSY
This bit indicates that the PrimeCell KMI is currently receiving data. 0 = idle, 1 = receiving data.
4
RXFULL
This bit indicates that the receiver register is full and ready to be read. 0 = receive register empty, 1 = receive register full, ready to be read.
5
TXBUSY
This bit indicates that the PrimeCell KMI is currently sending data. 0 = idle, 1 = currently sending data.
6
TXEMPTY
This bit indicates that the transmit register is empty and ready to transmit. 0 = transmit register full, 1 = transmit register empty, ready to be written.
7
-
Reserved. Read unpredictable.
Здесь используется стандартный набор 2 скан-кодов AT-клавиатуры:
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
A
1C
F0,1C
9
46
F0,46
[
54
FO,54
B
32
F0,32
`
0E
F0,0E
INSERT
E0,70
E0,F0,70
C
21
F0,21
-
4E
F0,4E
HOME
E0,6C
E0,F0,6C
D
23
F0,23
=
55
FO,55
PG UP
E0,7D
E0,F0,7D
E
24
F0,24
\
5D
F0,5D
DELETE
E0,71
E0,F0,71
F
2B
F0,2B
BKSP
66
F0,66
END
E0,69
E0,F0,69
G
34
F0,34
SPACE
29
F0,29
PG DN
E0,7A
E0,F0,7A
H
33
F0,33
TAB
0D
F0,0D
U ARROW
E0,75
E0,F0,75
I
43
F0,43
CAPS
58
F0,58
L ARROW
E0,6B
E0,F0,6B
J
3B
F0,3B
L SHFT
12
FO,12
D ARROW
E0,72
E0,F0,72
K
42
F0,42
L CTRL
14
FO,14
R ARROW
E0,74
E0,F0,74
L
4B
F0,4B
L WIN
E0,1F
E0,F0,1F
NUM
77
F0,77
M
3A
F0,3A
L ALT
11
F0,11
KP /
E0,4A
E0,F0,4A
N
31
F0,31
R SHFT
59
F0,59
KP *
7C
F0,7C
O
44
F0,44
R CTRL
E0,14
E0,F0,14
KP -
7B
F0,7B
P
4D
F0,4D
R WIN
E0,27
E0,F0,27
KP +
79
F0,79
Q
15
F0,15
R ALT
E0,11
E0,F0,11
KP EN
E0,5A
E0,F0,5A
R
2D
F0,2D
APPS
E0,2F
E0,F0,2F
KP .
71
F0,71
S
1B
F0,1B
ENTER
5A
F0,5A
KP 0
70
F0,70
T
2C
F0,2C
ESC
76
F0,76
KP 1
69
F0,69
U
3C
F0,3C
F1
05
F0,05
KP 2
72
F0,72
V
2A
F0,2A
F2
06
F0,06
KP 3
7A
F0,7A
W
1D
F0,1D
F3
04
F0,04
KP 4
6B
F0,6B
X
22
F0,22
F4
0C
F0,0C
KP 5
73
F0,73
Y
35
F0,35
F5
03
F0,03
KP 6
74
F0,74
Z
1A
F0,1A
F6
0B
F0,0B
KP 7
6C
F0,6C
0
45
F0,45
F7
83
F0,83
KP 8
75
F0,75
1
16
F0,16
F8
0A
F0,0A
KP 9
7D
F0,7D
2
1E
F0,1E
F9
01
F0,01
]
5B
F0,5B
3
26
F0,26
F10
09
F0,09
;
4C
F0,4C
4
25
F0,25
F11
78
F0,78
'
52
F0,52
5
2E
F0,2E
F12
07
F0,07
,
41
F0,41
6
36
F0,36
PRNT
SCRN
E0,12,
E0,7C
E0,F0,
7C,E0,
F0,12
.
49
F0,49
7
3D
F0,3D
SCROLL
7E
F0,7E
/
4A
F0,4A
8
3E
F0,3E
PAUSE
E1,14,77,
E1,F0,14,
F0,77
-NONE-
То есть каждая клавиша имеет скан-коды для нажатия (make) и для отпускания (break). Так, при нажатии клавиши "A" мы получаем скан-код 0x1C, и продолжаем получать его вплоть до отпускания клавиши. А в момент отпускания генерируется двухбайтный скан-код 0xF0, 0x1C.
Теперь для тренировки вы можете попробовать подправить программу таким образом, чтобы она выводила не скан-код клавиши, а непосредственно её значение.
Smalovsky
27.08.2023, 15:46
Для программирования голого распберри есть версия Лазаруса -Ультибо.
http://www.freepascal.ru/forum/viewtopic.php?t=11237
https://ultibo.org/wiki/Main_Page
https://ultibo.org/
Есть графический движок для Ультибо https://bshark.org/
CityAceE
27.08.2023, 17:05
Для программирования голого распберри есть версия Лазаруса -Ультибо.
Да, спасибо, я встречал уже упоминания о Ultbio. А ещё народ на Си пишет серьёзные вещи под голое железо с использованием уже упоминавшейся библиотеки Circle. Отличный пример такого результата - эмулятор ZXBaremulator. Это всё хорошо, но такие решения по сути своей ничем не отличаются от обычного программирования на языках высокого уровня - всю работу по обслуживанию железа берут на себя библиотеки, не важно через операционную систему или напрямую. А, как я уже писал, для меня программирование на ассемблере голого железа - это своего рода спорт. В данном случае результат - дело второе, важнее сам процесс. Мне лично это доставляет точно такое же удовольствие, как и программирование на Спектруме. А особенно, если что-то получается ;)
CityAceE
29.08.2023, 10:31
Не знаю, заметили вы или нет, но примеры, которые я привёл выше, хоть и написаны на ассемблере для процессора ARM, который лежит в основе Raspberry Pi, не предназначены для запуска из на Raspberry Pi. Приведённые примеры относятся к плате разработке Arm Versatile Express. О чем говорит ключ запуска эмулятора QEMU "-M vexpress-a9"
Есть несколько разновидностей этого устройства и выглядят они примерно так:
https://pic.maxiol.com/thumbs2/1693294689.3280329127.versatileexpressin.jpg (https://pic.maxiol.com/?v=1693294689.3280329127.versatileexpressin.jpg&dp=2) https://pic.maxiol.com/thumbs2/1693294707.3280329127.vexpress1.jpg (https://pic.maxiol.com/?v=1693294707.3280329127.vexpress1.jpg&dp=2)
На задней панели выведены следующие разъёмы и порты:
https://pic.maxiol.com/images2/1693294895.3280329127.v2mp1rearpanel.png
Одних только UART можно насчитать 4 шт.!
Данная плата предназначена прежде всего для разработчиков и в свободной продаже отсутствовала. Но я выбрал его в качестве целевой просто потому, что именно для неё я нашёл первые примеры на ассемблере с выводом графики (помните демо FreeFull?), которые можно было скомпилировать и запустить под эмулятором QEMU. При этом эмулятор поддерживает необходимый минимум устройств:
PL041 audio
PL181 SD controller
PL050 keyboard and mouse
PL011 UARTs
SP804 timers
I2C controller
PL031 RTC
PL111 LCD display controller
Flash memory
LAN9118 ethernet
И программируется всё это легко, так как адресуется, как обычная память (MMIO). Пример инициализации и работы с графическим экраном (PL111) есть, с клавиатурой (PL050) я тоже привёл. Не хватает реализации работы с внешним накопителем (PL181), и неплохо бы ещё уметь программировать звук (PL041). Но, опять же, адреса этих устройств известны, и при достаточном усердии и с ними тоже можно научиться работает. И всё бы хорошо, но реальные устройства - это слишком нишевый продукт, да ещё и недоступный для простых смертных.
Другое дело Raspberry Pi - одна из моделей скорее всего лежит где-нибудь в закромах у многих! Но тут обратная ситуация, во-первых всё программируется сложнее, так как прямого доступа к железу всё-таки нет, а во-вторых все примеры, которые можно найти запускаются исключительно на реальном железа, а под эмулятором они же работать не хотят.
Вот поэтому я начал своё изучение ARM с платформы Arm Versatile Express под эмулятором параллельно пытаясь разобраться как всё-таки можно что-то писать под Raspberry Pi и потом запускать не только на реальном железе, но и под эмулятором для отладки. И мои старания не прошли даром, мне удалось таки решить эту задачу.
А в заключении этого сообщения хочу поделиться с вами ссылкой на страничку Arm IntrO Challenge (https://io.netgarage.org/arm/), где помимо уже опубликованной демки FreeFull, есть ещё несколько примеров на ассемблере для Arm Versatile Express.
https://io.netgarage.org/arm/digitalcold2.png
https://io.netgarage.org/arm/blasty1.png
CityAceE
30.08.2023, 19:46
А теперь давайте перейдём непосредственно к Raspberry Pi. Если вы, как и я, всерьёз интересовались bare metal программированием Raspberry Pi, то вы довольно быстро вышли на репозиторий Perter'а Lemon'а aka krom. О нём я уже упоминал в одном из предыдущих постов.
Вот адрес этого замечательного репозитория: https://github.com/PeterLemon/RaspberryPi
Здесь автор на чистом bare metal ассемблере на примерах показывает как запрограммировать то или иное действие на Raspberry Pi. Здесь вы найдёте примеры "Hello, World!" в графическом режиме, опроса геймпада NES, подключенного к GPIO-порту, вывод звука в разных режимах, анимацию фракталов, и даже вывод видео! А также много чего ещё, включая эмулятор GameBoy. Это поистине бесценная кладезь примеров! И там помимо исходных текстов сразу лежат скомпилированные бинариники для запуска на реальных микрокомпьютерах Raspberry Pi. И я лично убедился, что они работают! Рекомендую и вам сделать то же самое. Для этого нужно всего лишь скачать с репозитория скомпилированные ядра (kernel*.img) и записать их на SD-карту вместо существующих, рядом с другими системными файлами. Более подробно о загрузке Raspberry Pi я писал ранее (https://blog.reext.ru/kak-zagruzhaetsya-raspberry-pi/).
Но при попытке запустить эти примеры под эмулятором, вас будет встречать лишь чёрный экран. Собственно, и меня он встречал. А когда я спросил Питера, как же он отлаживал свой код, он мне ответил, что после того, как написал что-то и откомпилировал, он честно записывал всё на SD-карту и проверял что получилось на реальной Raspberry Pi. То есть никакого отладчика и никакого эмулятора. Капец, как грустно! Я так точно не умею! И это на фоне того, что мне так и не удалось найти ни одного упоминания о том, что кто-то что-то запустил под эмулятором QEMU, кроме RaspbianOS с кастомным ядром.
Однако в итоге выяснилось, что всё не настолько печально! И вот вам в качестве доказательства пара скриншотов программ Питера Лемона, запущенных под эмулятором QEMU:
https://pic.maxiol.com/thumbs2/1693413933.780858384.mondelbrot.png (https://pic.maxiol.com/?v=1693413933.780858384.mondelbrot.png&dp=2) https://pic.maxiol.com/thumbs2/1693413985.780858384.videos.png (https://pic.maxiol.com/?v=1693413985.780858384.videos.png&dp=2)
Kakos_nonos
31.08.2023, 10:02
Очень интеесная тема! Спасибо!
CityAceE
01.09.2023, 09:15
Прежде чем окончательно перейти к теме эмуляции, мне хочется рассказать про ещё один метод отладки программ прямо на железе.
Первые bare metal программы начали появляться практически сразу после выхода Raspberry Pi. Понятное дело, что про эмуляцию на тот момент речи не шло, так как платформа только-только вышла. И поэтому энтузиасты вслепую писали свой код, далее записывали скомпилированное ядро на SD-карту и проверяли его работоспособность непосредственно на железе.
Вот так выглядела типичная проверка кода без какого-либо инструментария:
Выключаем Raspberry Pi
Извлекаем из неё SD-карту
Вставляем SD-карту в кард-ридер
Подключаем кард-ридер к компьютеру
Монтируем карту и ждём
Копируем бинарный файл на SD-карту
Синхронизируемся и ждём
Размонтируем карту
Вставляем SD-карту в Raspberry Pi
Включаем Raspberry Pi
Начинаем всё сначала
Очень долго и муторно. А ведь именно так и отлаживал свои программы упомянутый мной выше Питер Лемон. Но, к счастью, энтузиаст David Welch (dwelch67) придумал и воплотил метод, который существенно облегчил жизнь bare metal программистам. Суть метода заключается в том, что на SD-карту один раз записывается загрузчик, а сама Raspberry Pi подключается к компьютеру посредством USB-TTL адаптера:
https://pic.maxiol.com/thumbs2/1693548887.3280329127.uart1.jpg (https://pic.maxiol.com/?v=1693548887.3280329127.uart1.jpg&dp=2)
https://pic.maxiol.com/thumbs2/1693548916.3280329127.uart2.jpg (https://pic.maxiol.com/?v=1693548916.3280329127.uart2.jpg&dp=2)
Подключение осуществляется всего тремя проводами к разъёму GPIO:
GPIO6 - GND
GPIO8 - RXD
GPIO10 - TXD
https://pic.maxiol.com/thumbs2/1693674957.780858384.uartraspberrypi.png (https://pic.maxiol.com/?v=1693674957.780858384.uartraspberrypi.png&dp=2)
Единственная задача загрузчика - загрузка файла по UART в ОЗУ и передача ему управления. Это мне напомнило загрузку компьютер Вектор-06Ц, только там использовался не UART, а магнитофонный порт :) Сам загрузчик располагается по адресу 0x200000, то есть у вас есть 0x200000 байт (2 Мб) под собственную программу.
Таким образом, с помощью этого загрузчика всё сводится к следующим действиям:
Выключаем Raspberry Pi
Включаем Raspberry Pi
На компьютере набираем команду передачи файла.
Но всё можно ещё более упростить, если распаять кнопку RESET, пины под которую есть на всех моделях (http://www.noveldevices.co.uk/rp-project-reset) Raspberry Pi:
https://pic.maxiol.com/thumbs2/1693549715.3280329127.rpireset.jpg (https://pic.maxiol.com/?v=1693549715.3280329127.rpireset.jpg&dp=2)
Так вот если эту кнопку распаять, то первые два пункта сводятся просто к нажатию на RESET.
Думаю, что такой метод отладки не потерял своей актуальности и сегодня, когда QEMU более-менее сносно научился эмулировать Raspberry Pi.
Ну и в заключении приведу ссылку на репозиторий с исходниками и скомпилированным загрузчиком (есть несколько его версий), о котором шла речь в этом сообщении: https://github.com/dwelch67/raspberrypi
CityAceE
03.09.2023, 10:32
Отснял небольшой ролик с демонстрации работы загрузки по UART:
https://youtu.be/Q6lSKKkWipk
Используемый загрузчик: https://github.com/dwelch67/raspberrypi/blob/master/bootloader05/kernel.img
Самая первая программа (мигание светодиодом): https://github.com/dwelch67/raspberrypi/blob/master/blinker01/blinker01.bin
В видео используется вот этот терминал: https://www.emtec.com/zoc/index.html
Если кто-то знает какой-то терминал попроще и побесплатнее, и который ещё заработает в этой связке, то пожалуйста, поделитесь ссылкой.
UPDATE
Нашёл ещё одну терминальную программу, которая успешно передаёт файлы. На этот раз программа бесплатная и с исходниками. Называется Tera Term (http://ttssh2.osdn.jp/).
https://pic.maxiol.com/images2/1693739854.780858384.terraterm.png
Не знаю проблема ли это моего конкретного адаптера или, возможно, это везде так, но нормальное общение и передача данных возможна только на скорости 115200 бит/сек - ни больше, ни меньше. Имейте это ввиду, если вдруг захотите тоже попробовать.
CityAceE
06.09.2023, 12:53
Ну вот теперь мы вплотную приблизились к эмулятору Raspberry Pi. На самом деле я мог бы сейчас одной фразой сказать, как скомпилировать программу, чтобы она запустилась на эмуляторе. Но, думаю, что так будет менее интересно. Судя по активности, данная тема заинтересовала лишь 2-3 человека, да и для них, скорее всего интересен не конечный результат, а повествование. Поэтому я расскажу, как я пришёл к конечному результату, шаг за шагом.
Для того, чтобы писать приложения под операционную систему особенно не требуется каких-то изощрений. Писать и отлаживать можно прямо на Raspberry Pi. Другое дело низкоуровневое программирование - bare metal. Здесь нужно либо поверять написанную программу на реальном железе, либо иметь эмулятор. Правда в итоге написанную программу всё равно придётся запускать на настоящем микрокомпьютере, так как ни один эмулятор не способен обеспечить 100%-ного качества эмуляции. Пик интереса к bare metal программированию пришёлся на 7-10 лет назад, спустя короткое время после выхода Raspberry Pi, когда этот микрокомпьютер утвердился в качестве некоего стандарта, и когда появилось достаточное количество информации о его схемотехнике. Но на тот момент вообще не существовало какого-либо эмулятора этого устройства. Да, уже тогда существовал QEMU, который неплохо эмулировал устройства, базирующие на архитектуре ARM, но среди них не было платформы Raspberry Pi. Разработчики игры PiFox, очевидно для удобства отладки, на базе QEMU сделали свой эмулятор, который худо-бедно мог эмулировать архитектуру Raspberry Pi. Доводилось мне читать упоминания и о других подобных начинаниях. Но в конечном итоге, спустя несколько лет в QEMU появилась официальная поддержка Raspberry Pi. И начали они с эмуляции Raspberry Pi 2. А на сегодня мы имеем возможность эмулировать Raspberry Pi 1, 2, 3 и Zero.
Когда я только начал изучать вопрос, то поиски приводили меня лишь к всевозможным инструкциям для запуска RaspbianOS на QEMU. Сам запуск осуществлялся на кастомном ядре и на архитектуре отличной от Raspberry Pi - Arm Versatile (https://www.qemu.org/docs/master/system/arm/versatile.html). Предлагались инструкции (https://habr.com/ru/articles/216205/) по самостоятельным конфигурированию и сборке ядра, также готовые ядра (https://github.com/dhruvvyas90/qemu-rpi-kernel) под разные версии RaspbianOS. Но в итоге в QEMU завезли нативную эмуляцию Raspberry Pi и появилась возможность использовать стандартное ядро для запуска RaspbianOS. Правда, ядро не может подхватываться из образа, его предварительно необходимо оттуда извлечь, положить рядом с загружаемым образом и прописать в ключ запуска.
Вот так примерно будет выглядеть довольно длинная строка запуска нативной эмуляции RaspbianOS:
qemu-system-aarch64 -M raspi3b -append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootdelay=1" -dtb ./dtbs/bcm2710-rpi-3-b-plus.dtb -sd 2020-08-20-raspios-buster-armhf-full.img -kernel kernel8.img -m 1G -smp 4 -serial stdio -usb -device usb-mouse -device usb-kbd
И действительно, всё загружается и работает. Только это никак не помогает понять как же загрузить свою собственную программу в эмулятор QEMU. Из всего этого стало лишь понятно, что нужен особым образом скомпилированный kernel. И что я только не делал, как только не экспериментировал, но моя программа отказывалась запускаться под эмулятором. Вот оно по всем законам должно работать, но работает! И, честно сказать, руки мои практически опустились. Но тут мои поиски привели меня вот к этому примеру (https://github.com/mmuszkow/NoOsBootstrap/tree/master/arm). Этот пример написан на ассемблере, он в графическом виде выводит надпись "NO OS" на экран, а также выводит надпись "No OS installed" в консоль. И при этом данный пример должен был запускаться под эмулятором! (Тоже скачайте его себе для экспериментов, я в дальнейшем буду объяснять всё именно на его примере!)
И у меня получилось скомпилировать и запустить эту простую программу под эмулятором!
https://pic.maxiol.com/thumbs2/1693756522.780858384.noos1.png (https://pic.maxiol.com/?v=1693756522.780858384.noos1.png&dp=2) https://pic.maxiol.com/thumbs2/1693756543.780858384.noos2.png (https://pic.maxiol.com/?v=1693756543.780858384.noos2.png&dp=2)
Не скажу, что это было для меня просто, но у меня всё получилось. И вот тут пришло время немножко подробнее остановиться на средствах разработки.
FASMARM
В качестве кросс-ассемблера я остановил свой выбор на FASMARM. Я уже достоверно не помню как я на него вышел, но скорее всего потому что этот кросс-ассемблер фигурировал в примерах Питера Лемона. По своей сути FASMARM является аддоном для Flat Assembler и работает как под Windows, так и под Linux. Этот инструмент представляет из себя крохотный по сегодняшним меркам исполняемый файл. Он не требует инсталляции и не подтягивает какие-либо сторонние библиотеки.
Любопытно, что данный кросс-ассемблер сам написан на ассемблере. А что самое интересное - все последние версии FASMARM компилируются на Flat Assembler'е, то есть на самом себе.
Скачать сам ассемблер и его исходники можно с официальной странички: https://arm.flatassembler.net/
Использование его предельно простое:
fasmarm filename.s
А на выходе моментально получим готовый для запуска файл filename.bin.
Но определяющим при выборе ассемблера для меня стал всё-таки синтаксис. Дело в том, разные программы написанные на ассемблере ARM под разные компиляторы скорее всего потребуют доработок, а иногда весьма серьёзных из-за различий в синтаксисе. Например, FASMARM для обозначения комментариев использует привычную для меня точку с запятой ( ; ), а стандартные инструменты для этой же цели используют "собаку" ( @ ). Также весьма существенно отличается синтаксис макросов, обозначение чисел, наличие и отсутствие некоторых псевдокоманд. Нет смысла сейчас подробно останавливаться на этих различиях, а достаточно просто знать, что они есть.
Большую часть примеров, которые я находил в начале моего изучения, я смог скомпилировать на FASMARM либо вообще без переделок, либо с какими-то минимальными доработками. И вот как раз тот самый единственный найденный мной пример, который должен запускался под эмулятором, ни в какую не хотел переделываться под FASMARM. Да, к тому же ещё требовал линковки. Пришлось разбираться как компилировать другим инструментом. Оказалось, что там тоже нет ничего сложного.
Arm GNU Toolchain
Для начала нужно скачать инструментарий на сайте ARM. Инструментарий бесплатный, но с недавних пор, чтобы скачать его из РФ придётся воспользоваться VPN или Tor.
Качаем с этой страницы: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
Прямую ссылку на установочный файл не привожу, так как с выходом новых версий она меняется. Но вам нужно будет скачать примерно такой файл: arm-gnu-toolchain-12.3.rel1-mingw-w64-i686-arm-none-eabi.exe ,где:
w64-i686 - платформа компилятора Windows 64 бит
arm-none-eabi - целевая платформа ARM 32 бит
Скачиваем и устанавливаем.
Чтобы скомпилировать тот самый пример я подготовил вот такой bat-файл, основываясь на информации из Makefile:
@set file=boot-arm-raspi
@set toolchain="c:\Program Files (x86)\Arm GNU Toolchain arm-none-eabi\12.3 rel1\bin\arm-none-eabi"
python bmp2inc.py > bmp_no_os.inc
%toolchain%-as -o %file%.o -mcpu=arm1176jzf-s %file%.s
%toolchain%-ld -o %file%.elf -Ttext 0x8000 %file%.o
@if exist %file%.o del %file%.o
На выходе получаем boot-arm-raspi.elf, который можем запустить в эмуляторе следующей командой:
"c:\Program Files\qemu\qemu-system-arm.exe" -M raspi2b -serial stdio -kernel boot-arm-raspi.elf
Оказалось, что QEMU может обрабатывать elf-файлы, забирая оттуда всю необходимую для запуска информацию.
И всё бы хорошо, но этот вариант годится только для компилирования исходников с помощью Arm GNU Toolchain, а мне хотелось как и раньше пользоваться FASMARM. И я в итоге разобрался как прикрутить FASMARM к этой цепочке.
Прежде всего в исходном тексте своей программы в самом начале нужно добавить вот такие строки:
format ELF
section '.text' executable
public _start
org 0x8000
_start:
А для компиляции я создал вот такой батник:
@set file=filename
@set toolchain="c:\Program Files (x86)\Arm GNU Toolchain arm-none-eabi\12.3 rel1\bin\arm-none-eabi"
fasmarm %file%.s
%toolchain%-ld.exe -o %file%.elf -Ttext 0x8000 %file%.o
@if exist %file%.o del %file%.o
Ну и сразу здесь же напишу, что на выходе вы можете получить не только elf, но и бинарный файл, который можно записать на SD-карту и запустить на реальной Raspberry Pi. Для этого в конец цепочки компиляции нужно добавить ещё одну строку:
%toolchain%-objcopy %file%.elf -O binary %file%.img
Собственно, это и есть рабочий рецепт, которым я и начал пользоваться. И на этом можно было бы завершить данное сообщение. Но оказалось, что на деле для запуска скомпилированых программ под эмулятором можно обойтись вообще без всех этих плясок с Arm GNU Toolchain. И всё делается предельно просто!
В процессе изучения другого вопроса, я натолкнулся на ключ QEMU "-d in_asm", который показывает в консоли последние выполненные команды. Я сделал и скомпилироваал простую программу, состоящую из одной строки:
lable: b lable
Я запустил её под эмулятором с указанным ключом. И что же я увидел:
https://pic.maxiol.com/images2/1693993410.780858384.deadloop.png
Данная команда работает по адресу 0x10000! Это очень странный адрес! 32-х битные приложения запускаются и работают с адреса 0x8000. Для старых ядер адрес запуска был нулевой (0x0000). (Этот адрес можно вернуть, если в системной файле Raspberry Pi config.txt прописать команду kernel_old = 1.) Есть ещё адрес 0x200000 - это адрес запуска 64-х битных бинарников. Но никогда и нигде мне не попадалось упоминание о 0x10000. Я попробовал скомпилировать и запустить первую попавшуюся программу с этого адреса. И она как ни в чём не бывало запустилась под QEMU! Всё оказалось до безобразия просто.
Для запуска под эмулятором вам нужно всего лишь в своём коде прописать org 0x10000! (Собственно, это и есть та самая фраза, которой можно было ограничиться в этом сообщении.)
Теперь вы можете брать примеры Питера Лемона, о которых говорилось выше, менять там ORG, компилировать, и запускать всё под QEMU.
CityAceE
27.02.2024, 10:01
Создал тематическую группу в Telegram. Кому интересна тема программирования на ассемблере под голое железо (bare metal), милости прошу.
https://t.me/bare_asm
Пока я там один, но рассчитываю хотя бы на десяток человек, разделяющих мой интерес.
CityAceE
07.03.2024, 08:22
Собственно рассказал то, что о чём уже писал в этой теме.
https://youtu.be/cSvmv0Iwx5I?si=TMtEVTBMalHD85tM
CityAceE, вторую часть анонсируем, не стесняемся. ;)
CityAceE
13.03.2024, 11:36
creator, вторая часть уже на канале пару дней как. Третья уже на подходе. Я просто не думал, что здесь это кому-то интересно. А если кому-то интересно, то тот на канал подписался.
https://youtu.be/fmvHJoLzar0
CityAceE
14.03.2024, 11:05
https://youtu.be/aoASJ94qSUI
CityAceE
15.03.2024, 11:05
В этом ролике, вооружившись полученными ранее знаниями, мы выведем на экран нашего эмулируемого устройства чёрно-белую картинку в стандартном формате BMP. В процессе познакомимся с ещё одной, даже двумя, интересными командами процессора ARM.
https://youtu.be/sdt0Apxt1SE
CityAceE
21.03.2024, 10:16
В этом ролике узнаем, что такое стек, для чего он нужен и как им пользоваться. В процессе познакомимся с парой полезных команд процессора ARM.
https://youtu.be/ff6EZshEBhk
Кстати Raspberry Pi5 разгоняется, и программирование на асме дает большие возможности для вычислений и дем, и всяких акселей типа pistorm.
>Дополнительно можно отметить обеспечение возможности разгона плат Raspberry Pi 5 через повышение тактовой частоты с CPU с 2.4 GHz до 3.14 GHz. Изначально прошивка не позволяла повышать частоту выше 3 GHz, но в неофициально выпущенном обновлении прошивки данное ограничение убрано и на плате теперь можно выставлять значения выше 3 GHz. Судя по отзывам пользователей стабильная работа при стресс-тестировании обеспечивается при выставлении частоты 3.14 GHz и использовании активного охлаждения. При более высоких значениях начинают возникать сбои.
https://www.opennet.ru/opennews/art.shtml?num=60798
CityAceE
21.03.2024, 12:24
Кстати Raspberry Pi5 разгоняется, и программирование на асме дает большие возможности для вычислений и дем
У меня есть стойкое убеждение, что отказ от любых прокладок в виде операционных систем превращает даже самую слабую Raspberry Pi в мощнейшую платфму. Если там писать в том же стиле, как пишут демы на Спектрум, то я даже представить не могу, чего можно достичь на Raspberry Pi с её-то мощностями и ресурсами.
Например, написать свою демомейкерскую ось на ARM асме с эффектами))), что-то типа Kolibri OS но с заточкой под демосцену, чтобы все было красиво и с 3d эффектами типа Compiz, и только на асме!
CityAceE
07.04.2024, 17:43
В этом ролике мы инициализируем кадровый буфер Raspbberry Pi, заполним его данными, и запустим результат под эмулятором.
https://youtu.be/zjJP3yEWx-E
CityAceE
14.04.2024, 21:07
В этом ролике мы нарисуем надпись "Hello, World!" в кадровом буфере, разберёмся с загрузкой Raspberry Pi и, наконец, запустим нашу программу на реальном железе.
https://youtu.be/MaPtB40IrDg
CityAceE
06.07.2024, 22:31
Приглашаю всех завтра в воскресенье 7 июля в 16.00 по Москве вместе со мной посмотреть новый ролик. Там я немного расскажу про baremetal эмулятор ZX Spectrum, написанный на ассемблере для Raspberry Pi. Найду и починю авторские ошибки и расскажу про инструмент, который я сделал для поиска ошибок эмуляции. Ролик снова получился длинным - 53 минуты, так что можете расценивать его как стрим, там более, что я буду в этот момент в чате премьеры вместе с вами.
https://youtu.be/z5eR7t2AMyo
Кстати, есть Purebasic 6 под платформу. Кто-нить пробовал?
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot