run: bare-metal hello boots on cortex-a7, emmc 8GiB real GPT33
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
/* hello guest: proves qemu cortex-a7 pipeline on zern. virt UART0 0x09000000. */
|
||||||
|
#define UART0 ((volatile unsigned int *)0x09000000)
|
||||||
|
static void uart_putc(char c) { *UART0 = (unsigned int)c; }
|
||||||
|
static void uart_puts(const char *s) { while (*s) uart_putc(*s++); }
|
||||||
|
void main(void) {
|
||||||
|
uart_puts("SAIMAA-STUB: cortex-a7 alive, RAM ok\r\n");
|
||||||
|
uart_puts("SAIMAA-STUB: next -> PBL reads SBL1 LBA 90112\r\n");
|
||||||
|
while (1) { }
|
||||||
|
}
|
||||||
Executable
+15
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run.sh — первый запуск: bare-metal hello на cortex-a7 + наш emmc.img на SDHCI.
|
||||||
|
# Ожидаем UART-привет. Это проверка трубы, не загрузка Lumia.
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
IMG=${IMG:-/tmp/emmc-test.img}
|
||||||
|
arm-none-eabi-gcc -nostartfiles -nostdlib -mcpu=cortex-a7 -marm \
|
||||||
|
-Wl,-Ttext=0x40008000 -o /tmp/hello.elf qemu/start.S qemu/hello.c 2>/dev/null
|
||||||
|
arm-none-eabi-objcopy -O binary /tmp/hello.elf /tmp/hello.bin
|
||||||
|
echo "[run] guest built, starting qemu (10s timeout)..."
|
||||||
|
timeout 10 qemu-system-arm -M virt -cpu cortex-a7 -m 1024 -nographic \
|
||||||
|
-kernel /tmp/hello.elf \
|
||||||
|
-drive file="$IMG",if=none,format=raw,id=emmc \
|
||||||
|
-device sdhci-pci -device sd-card,drive=emmc 2>&1 | head -10
|
||||||
|
echo "[run] exit=$? (124 = timeout после вывода = OK для вечного цикла)"
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
.section .text
|
||||||
|
.global _start
|
||||||
|
.arm
|
||||||
|
_start:
|
||||||
|
ldr sp, =0x40200000
|
||||||
|
bl main
|
||||||
|
hang:
|
||||||
|
b hang
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""mkimage.py — сборка emmc.img с РЕАЛЬНОЙ GPT RM-1127 (33 раздела).
|
||||||
|
Layout: Boot1 4M + Boot2 4M + RPMB 4M + User 15154944 секторов.
|
||||||
|
Пока разделы пустые (нули) — контент из FFU payload будет следующим шагом.
|
||||||
|
Использование: ./tools/mkimage.py images/emmc.img
|
||||||
|
"""
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import uuid
|
||||||
|
import zlib
|
||||||
|
|
||||||
|
SECTOR = 512
|
||||||
|
BOOT_MB = 4
|
||||||
|
RPMB_MB = 4
|
||||||
|
USER_SECTORS = 15154944 # MinSectorCount из FFU
|
||||||
|
# QEMU 6.2 sd-card требует power-of-2 размер: добиваем файл до 8GiB.
|
||||||
|
# GPT (primary+backup) остается на РЕАЛЬНЫХ смещениях User-области,
|
||||||
|
# хвост после User — нули (Windows увидит только primary GPT, WIP-допущение).
|
||||||
|
FILE_SIZE = 8 * 1024 * 1024 * 1024
|
||||||
|
|
||||||
|
BASIC = "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"
|
||||||
|
# (name, lba0, lba1, type_guid) — из tools/ffu_parse.py по orig FFU
|
||||||
|
PARTS = [
|
||||||
|
("DPP", 4096, 20479, BASIC),
|
||||||
|
("MODEM_FSG", 20480, 23551, "638ff8e2-22c9-e33b-8f5d-0e81686a68cb"),
|
||||||
|
("MODEM_FS1", 24576, 27647, "ebbeadaf-22c9-e33b-8f5d-0e81686a68cb"),
|
||||||
|
("MODEM_FS2", 28672, 31743, "0a288b1f-22c9-e33b-8f5d-0e81686a68cb"),
|
||||||
|
("MODEM_FSC", 32768, 32799, "57b90a16-22c9-e33b-8f5d-0e81686a68cb"),
|
||||||
|
("DDR", 36864, 36927, "20a0c19c-286a-42fa-9ce7-f64c3226a794"),
|
||||||
|
("LogFS", 40960, 73727, "bc0330eb-3410-4951-a617-03898dbe3372"),
|
||||||
|
("SSD", 73728, 73759, "2c86e742-745e-4fdd-bfd8-b6a7ac638772"),
|
||||||
|
("UEFI_BS_NV", 77824, 78335, "f0b4f48b-aeba-4ecf-9142-5dc30cdc3e77"),
|
||||||
|
("UEFI_RT_NV", 81920, 82431, "6bb94537-7d1c-44d0-9dfe-6d77c011dbfc"),
|
||||||
|
("BOOTMODE", 86016, 86047, "0e91ab96-8339-4ae4-a310-ed94357fd7d0"),
|
||||||
|
("SBL1", 90112, 91135, "dea0ba2c-cbdd-4805-b4f9-f428251c3e98"),
|
||||||
|
("DBI", 94208, 94271, "d4e0d938-b7fa-48c1-9d21-bc5ed5c4b203"),
|
||||||
|
("UEFI", 98304, 102399, "400ffdcd-22e0-47e7-9a23-f16ed9382388"),
|
||||||
|
("RPM", 102400, 103423, "098df793-d712-413d-9d4e-89d711772228"),
|
||||||
|
("QSEE", 106496, 108543, "a053aa7f-40b8-4b1c-ba08-2f68ac71a4f4"),
|
||||||
|
("QHEE", 110592, 111615, "e1a6a689-0c8d-4cc6-b4e8-55a4320fbd8a"),
|
||||||
|
("WINSECAPP", 114688, 115711, "69b4201f-a5ad-45eb-9f49-45b38ccdaef5"),
|
||||||
|
("TZAPPS", 118784, 151551, "14d11c40-2a3d-4f97-882d-103a1ec09333"),
|
||||||
|
("BACKUP_SBL1", 151552, 152575, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("BACKUP_DBI", 155648, 155711, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("BACKUP_UEFI", 159744, 163839, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("BACKUP_RPM", 163840, 164863, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("BACKUP_QSEE", 167936, 169983, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("BACKUP_QHEE", 172032, 173055, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("BACKUP_WINSECAPP", 176128, 177151, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("BACKUP_TZAPPS", 180224, 212991, "a3381699-350c-465e-bd5d-fa3ab901a39a"),
|
||||||
|
("PLAT", 212992, 229375, "543c031a-4cb6-4897-bffe-4b485768a8ad"),
|
||||||
|
("EFIESP", 229376, 360447, BASIC),
|
||||||
|
("MMOS", 360448, 372735, BASIC),
|
||||||
|
("SEC", 372736, 372767, "303e6ac3-af15-4c54-9e9b-d9a8fbecf401"),
|
||||||
|
("MainOS", 376832, 4089855, BASIC),
|
||||||
|
("Data", 4096000, 15150847, BASIC),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def gpt_header(nent, lba_backup, disk_guid, crc_entries, cur=1):
|
||||||
|
h = struct.pack("<8sIIIIQQQQ16sQIII",
|
||||||
|
b"EFI PART", 0x10000, 92, 0, 0, cur, lba_backup,
|
||||||
|
34, USER_SECTORS - 34,
|
||||||
|
disk_guid.bytes_le, 2, nent, 128, crc_entries)
|
||||||
|
crc = zlib.crc32(h) & 0xFFFFFFFF
|
||||||
|
return struct.pack("<8sIIIIQQQQ16sQIII",
|
||||||
|
b"EFI PART", 0x10000, 92, crc, 0, cur, lba_backup,
|
||||||
|
34, USER_SECTORS - 34,
|
||||||
|
disk_guid.bytes_le, 2, nent, 128, crc_entries)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
out = sys.argv[1] if len(sys.argv) > 1 else "images/emmc.img"
|
||||||
|
pre = (BOOT_MB * 2 + RPMB_MB) * 1024 * 1024
|
||||||
|
total = FILE_SIZE
|
||||||
|
assert pre + USER_SECTORS * SECTOR <= total
|
||||||
|
print(f"[mkimage] {out}: boot {BOOT_MB}M x2 + rpmb {RPMB_MB}M + "
|
||||||
|
f"user {USER_SECTORS} sectors")
|
||||||
|
with open(out, "wb") as f:
|
||||||
|
f.truncate(total) # sparse
|
||||||
|
uoff = pre
|
||||||
|
# protective MBR
|
||||||
|
mbr = bytearray(512)
|
||||||
|
mbr[446:462] = struct.pack("<B3sB3sII", 0, b"\x00\x02\x00", 0xEE,
|
||||||
|
b"\xFF\xFF\xFF",
|
||||||
|
1, USER_SECTORS - 1)
|
||||||
|
mbr[510:512] = b"\x55\xAA"
|
||||||
|
f.seek(uoff)
|
||||||
|
f.write(mbr)
|
||||||
|
# entries
|
||||||
|
ent = bytearray(128 * 128)
|
||||||
|
for i, (name, a, b, t) in enumerate(PARTS):
|
||||||
|
e = struct.pack("<16s16sQQQ", uuid.UUID(t).bytes_le,
|
||||||
|
uuid.uuid4().bytes_le, a, b, 0)
|
||||||
|
e += name.encode("utf-16-le")[:72].ljust(72, b"\x00")
|
||||||
|
ent[i * 128:(i + 1) * 128] = e
|
||||||
|
crc_e = zlib.crc32(ent) & 0xFFFFFFFF
|
||||||
|
disk = uuid.uuid4()
|
||||||
|
f.seek(uoff + 512)
|
||||||
|
f.write(gpt_header(128, USER_SECTORS - 1, disk, crc_e))
|
||||||
|
f.seek(uoff + 1024)
|
||||||
|
f.write(ent)
|
||||||
|
# backup GPT at end of User
|
||||||
|
f.seek(uoff + (USER_SECTORS - 33) * SECTOR)
|
||||||
|
f.write(ent)
|
||||||
|
f.seek(uoff + (USER_SECTORS - 1) * SECTOR)
|
||||||
|
f.write(gpt_header(128, 1, disk, crc_e,
|
||||||
|
cur=USER_SECTORS - 1))
|
||||||
|
print(f"[mkimage] OK: {len(PARTS)} partitions, primary+backup GPT, CRC ok")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user