uzbek-plus/b5b/emu/shim.c
q 105bef466a Project Aurora: mainline ARM64 Linux on JZ08AU (MSM8916) LTE modem
Sanitized research log, build/reproducibility docs, DTS, kernel configs,
patches, initramfs sources, bootchain migration plans and test logs.
B5 direct boot PASS; B6 modem lifecycle in progress.
No dumps, NV/EFS, vendor firmware or device identifiers included.
2026-09-30 17:23:18 +03:00

120 lines
6.5 KiB
C

/* Host shim for running exact lk2nd 23.1 boot scan / extlinux / ext2 code against eMMC image files. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <openssl/sha.h>
#include "shim/partition_parser.h"
int _dprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); printf("[lk] "); int r = vprintf(fmt, ap); va_end(ap); return r; }
void platform_halt(void) { printf("HARNESS: platform_halt (panic)\n"); exit(3); }
void _panic(void *caller, const char *fmt, ...) { va_list ap; va_start(ap, fmt); printf("HARNESS: PANIC "); vprintf(fmt, ap); va_end(ap); exit(3); }
/* ---- virtual disk: LBA ranges -> files ---- */
struct seg { uint64_t lba, n; const char *file; int fd; };
static struct seg segs[64]; static int nsegs;
static uint64_t disk_sectors = 7634944;
static struct partition_entry ents[128]; static unsigned nents;
uint64_t reads_bytes;
static void load_map(const char *mapfile) {
FILE *f = fopen(mapfile, "r"); char path[512]; unsigned long long lba, n;
if (!f) { perror(mapfile); exit(2); }
while (fscanf(f, "%llu %llu %511s", &lba, &n, path) == 3) {
segs[nsegs].lba = lba; segs[nsegs].n = n; segs[nsegs].file = strdup(path);
segs[nsegs].fd = open(path, O_RDONLY); if (segs[nsegs].fd < 0) { perror(path); exit(2); }
off_t sz = lseek(segs[nsegs].fd, 0, SEEK_END);
if ((uint64_t)sz < n * 512) { fprintf(stderr, "short file %s\n", path); exit(2); }
nsegs++;
}
fclose(f);
}
static void load_gpt(const char *gptfile) {
unsigned char g[17408]; int fd = open(gptfile, O_RDONLY); if (fd < 0 || read(fd, g, sizeof g) != sizeof g) { perror(gptfile); exit(2); }
close(fd);
for (int i = 0; i < 128; i++) {
unsigned char *e = g + 1024 + 128 * i; int z = 1; for (int k = 0; k < 16; k++) if (e[k]) z = 0; if (z) continue;
memcpy(&ents[nents].first_lba, e + 32, 8); memcpy(&ents[nents].last_lba, e + 40, 8);
ents[nents].size = ents[nents].last_lba - ents[nents].first_lba + 1;
for (int k = 0; k < 36; k++) ents[nents].name[k] = e[56 + 2 * k];
nents++;
}
}
struct partition_entry *partition_get_partition_entries(void) { return ents; }
unsigned partition_get_partition_count(void) { return nents; }
uint32_t mmc_get_device_blocksize(void) { return 512; }
uint64_t mmc_get_device_capacity(void) { return disk_sectors * 512; }
uint32_t mmc_read(uint64_t addr, uint32_t *out, uint32_t len) {
uint8_t *o = (uint8_t *)out; reads_bytes += len;
while (len) {
uint64_t lba = addr / 512; struct seg *s = NULL;
for (int i = 0; i < nsegs; i++) if (lba >= segs[i].lba && lba < segs[i].lba + segs[i].n) s = &segs[i];
if (!s) { fprintf(stderr, "HARNESS: read of unmapped LBA %llu\n", (unsigned long long)lba); exit(4); }
uint64_t end = (s->lba + s->n) * 512, chunk = end - addr; if (chunk > len) chunk = len;
if (pread(s->fd, o, chunk, addr - s->lba * 512) != (ssize_t)chunk) { perror("pread"); exit(4); }
o += chunk; addr += chunk; len -= chunk;
}
return 0;
}
/* writes must never happen */
uint32_t mmc_write(uint64_t a, uint32_t l, void *b) { (void)a;(void)l;(void)b; fprintf(stderr, "HARNESS: WRITE ATTEMPT\n"); abort(); }
/* ---- target / platform ---- */
uint8_t *fake_ddr; static uint8_t *scratch;
void *target_get_scratch_address(void) { return scratch; }
unsigned target_get_max_flash_size(void) { return 256u * 1024 * 1024; }
unsigned board_machtype(void) { return 0; }
void arch_clean_invalidate_cache_range(uintptr_t a, size_t l) { (void)a; (void)l; }
const char *const *lk2nd_device_get_dtb_hints(void) { return NULL; }
int fdt_open_into(const void *f, void *b, int s) { (void)f;(void)b;(void)s; return -1; }
int fdt_overlay_apply(void *f, void *o) { (void)f;(void)o; return -1; }
int fdt_pack(void *f) { (void)f; return -1; }
static void hx(const char *what, const void *p, size_t n) {
unsigned char h[32]; SHA256(p, n, h); printf("HARNESS: %-8s sha256 ", what); for (int i = 0; i < 32; i++) printf("%02x", h[i]); printf(" (%zu bytes)\n", n);
}
void boot_linux(void *kernel, unsigned *tags, const char *cmdline, unsigned machtype, void *ramdisk, unsigned ramdisk_size, int boot_type) {
(void)machtype;
uint32_t *k = kernel; uint64_t image_size; memcpy(&image_size, (uint8_t *)kernel + 16, 8);
uint32_t dtsz = __builtin_bswap32(tags[1]);
printf("HARNESS: boot_linux reached: kernel @DDR+0x%lx tags @DDR+0x%lx ramdisk @DDR+0x%lx (%u) boot_type %d\n",
(long)((uint8_t *)kernel - fake_ddr), (long)((uint8_t *)tags - fake_ddr), (long)((uint8_t *)ramdisk - fake_ddr), ramdisk_size, boot_type);
printf("HARNESS: kernel magic 0x%08x image_size 0x%llx end @DDR+0x%llx\n", k[14], (unsigned long long)image_size,
(unsigned long long)((uint8_t *)kernel - fake_ddr) + image_size);
printf("HARNESS: cmdline '%s'\n", cmdline);
extern unsigned harness_kernel_len; hx("kernel", kernel, harness_kernel_len);
hx("dtb", tags, dtsz); hx("ramdisk", ramdisk, ramdisk_size);
exit(0);
}
unsigned harness_kernel_len = 23015432;
void lk2nd_boot(void);
void bio_init(void);
void fs_init(void);
void ext2_init(void);
int main(int argc, char **argv) {
if (argc < 3) { fprintf(stderr, "usage: %s map gpt [kernel_len]\n", argv[0]); return 2; }
if (argc > 3) harness_kernel_len = strtoul(argv[3], 0, 0);
setvbuf(stdout, NULL, _IONBF, 0);
fake_ddr = calloc(1, 0x3200000); scratch = calloc(1, 256u * 1024 * 1024);
load_map(argv[1]); load_gpt(argv[2]);
bio_init(); fs_init();
lk2nd_boot();
printf("HARNESS: lk2nd_boot() returned -> aboot would continue to boot_linux_from_mmc() (Android boot partition)\n");
{ /* diagnostics: mount result per scan candidate, same criteria as lk2nd_scan_devices */
extern struct bdev_struct *bio_get_bdevs(void); extern int fs_mount(const char*,const char*,const char*); extern int fs_unmount(const char*);
struct hl { struct hl *prev, *next; };
struct hb { struct hl node; volatile int ref; char *name; long long size; size_t block_size; uint32_t block_count; char *label; _Bool is_leaf; };
struct hl *head = (struct hl *)bio_get_bdevs();
for (struct hl *n = head->next; n != head; n = n->next) { struct hb *b = (struct hb *)n; char mp[32];
if (!b->is_leaf) continue;
if (b->size < 16*1024*1024 && !(b->label && !strncmp(b->label, "boot", 4))) continue;
snprintf(mp, sizeof mp, "/diag-%s", b->name); int r = fs_mount(mp, "ext2", b->name);
printf("HARNESS: scan-candidate %-8s (%s) ext2 mount rc=%d\n", b->name, b->label ? b->label : "", r); if (r == 0) fs_unmount(mp); } }
printf("HARNESS: total bytes read %llu\n", (unsigned long long)reads_bytes);
return 1;
}
int atomic_add(volatile int *p, int v) { int o = *p; *p = o + v; return o; }