/* SPDX-License-Identifier: GPL-2.0+ */ /* * load.c - pull the payload into RAM. semihosting is the whole story * for now, the bios INT 13h of this loader: the host serves the file, * we read it at the fixed address and let the image header place it. * * Copyright (C) 2026 Bradley Morgan */ #include #include #include #include #include #include int tb_load_semihosting(const char *fname, uintptr_t load_addr, struct tb_image *img) { long fd, len, ret; fd = smh_open(fname, MODE_READ | MODE_BINARY); if (fd < 0) return fd; len = smh_flen(fd); if (len < 0) { smh_close(fd); return len; } /* header first so placement is known before the big copy */ ret = smh_read(fd, (void *)load_addr, 64); if (ret != 64) { smh_close(fd); return -3; } if (tb_image_setup(load_addr, img)) { smh_close(fd); return -4; } if (img->load != load_addr) { /* the image wants to sit elsewhere, copy the header there */ memmove((void *)img->load, (void *)load_addr, 64); } ret = smh_read(fd, (void *)(img->load + 64), len - 64); if (ret != len - 64) { smh_close(fd); return -5; } smh_close(fd); return 0; } /* * the initrd path, no header, no placement math, bytes to the * address the dtb /chosen already names. */ int tb_load_raw(const char *fname, uintptr_t load_addr) { long fd, len, ret; fd = smh_open(fname, MODE_READ | MODE_BINARY); if (fd < 0) return fd; len = smh_flen(fd); if (len < 0) { smh_close(fd); return len; } ret = smh_read(fd, (void *)load_addr, len); smh_close(fd); if (ret != len) return -6; return 0; }