I added support for vmctl -cL -B net -b bsd.rd -d disk.img to run the
autoinstall by emulating a PXE boot. In the commit
https://github.com/openbsd/src/commit/a13de4d12a4c9ba0edc05aab2ad635f782449229
the feature got removed over eagerly.
This diff adds this back because I find this super practical.
--
:wq Claudio
Index: loadfile.h
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/loadfile.h,v
retrieving revision 1.15
diff -u -p -r1.15 loadfile.h
--- loadfile.h 16 Jun 2021 16:55:02 -0000 1.15
+++ loadfile.h 22 Dec 2021 14:34:06 -0000
@@ -80,7 +80,8 @@
#define PML2_PAGE 0x13000
#define NPTE_PG (PAGE_SIZE / sizeof(uint64_t))
-int loadfile_elf(gzFile, struct vm_create_params *, struct vcpu_reg_state *);
+int loadfile_elf(gzFile, struct vm_create_params *, struct vcpu_reg_state *,
+ unsigned int);
size_t mread(gzFile, paddr_t, size_t);
Index: loadfile_elf.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/loadfile_elf.c,v
retrieving revision 1.39
diff -u -p -r1.39 loadfile_elf.c
--- loadfile_elf.c 4 May 2021 10:48:51 -0000 1.39
+++ loadfile_elf.c 22 Dec 2021 14:38:55 -0000
@@ -118,7 +118,7 @@ static void setsegment(struct mem_segmen
static int elf32_exec(gzFile, Elf32_Ehdr *, u_long *, int);
static int elf64_exec(gzFile, Elf64_Ehdr *, u_long *, int);
static size_t create_bios_memmap(struct vm_create_params *, bios_memmap_t *);
-static uint32_t push_bootargs(bios_memmap_t *, size_t);
+static uint32_t push_bootargs(bios_memmap_t *, size_t, bios_bootmac_t *);
static size_t push_stack(uint32_t, uint32_t);
static void push_gdt(void);
static void push_pt_32(void);
@@ -264,13 +264,14 @@ push_pt_64(void)
*/
int
loadfile_elf(gzFile fp, struct vm_create_params *vcp,
- struct vcpu_reg_state *vrs)
+ struct vcpu_reg_state *vrs, unsigned int bootdevice)
{
int r, is_i386 = 0;
uint32_t bootargsz;
size_t n, stacksize;
u_long marks[MARK_MAX];
bios_memmap_t memmap[VMM_MAX_MEM_RANGES + 1];
+ bios_bootmac_t bm, *bootmac = NULL;
if ((r = gzread(fp, &hdr, sizeof(hdr))) != sizeof(hdr))
return 1;
@@ -301,8 +302,12 @@ loadfile_elf(gzFile fp, struct vm_create
else
push_pt_64();
+ if (bootdevice & VMBOOTDEV_NET) {
+ bootmac = &bm;
+ memcpy(bootmac, vcp->vcp_macs[0], ETHER_ADDR_LEN);
+ }
n = create_bios_memmap(vcp, memmap);
- bootargsz = push_bootargs(memmap, n);
+ bootargsz = push_bootargs(memmap, n, bootmac);
stacksize = push_stack(bootargsz, marks[MARK_END]);
vrs->vrs_gprs[VCPU_REGS_RIP] = (uint64_t)marks[MARK_ENTRY];
@@ -382,9 +387,9 @@ create_bios_memmap(struct vm_create_para
* The size of the bootargs
*/
static uint32_t
-push_bootargs(bios_memmap_t *memmap, size_t n)
+push_bootargs(bios_memmap_t *memmap, size_t n, bios_bootmac_t *bootmac)
{
- uint32_t memmap_sz, consdev_sz, i;
+ uint32_t memmap_sz, consdev_sz, bootmac_sz, i;
bios_consdev_t consdev;
uint32_t ba[1024];
@@ -408,6 +413,15 @@ push_bootargs(bios_memmap_t *memmap, siz
memcpy(&ba[i + 3], &consdev, sizeof(bios_consdev_t));
i += consdev_sz / sizeof(int);
+ if (bootmac) {
+ bootmac_sz = 3 * sizeof(int) + (sizeof(bios_bootmac_t) + 3) &
~3;
+ ba[i] = 0x7; /* bootmac */
+ ba[i + 1] = bootmac_sz;
+ ba[i + 2] = bootmac_sz;
+ memcpy(&ba[i + 3], bootmac, sizeof(bios_bootmac_t));
+ i += bootmac_sz / sizeof(int);
+ }
+
ba[i++] = 0xFFFFFFFF; /* BOOTARG_END */
write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE);
@@ -485,7 +499,7 @@ mread(gzFile fp, paddr_t addr, size_t sz
const char *errstr = NULL;
int errnum = 0;
size_t ct;
- size_t i, rd, osz;
+ size_t i, osz;
char buf[PAGE_SIZE];
/*
@@ -493,7 +507,6 @@ mread(gzFile fp, paddr_t addr, size_t sz
* write_mem
*/
ct = 0;
- rd = 0;
osz = sz;
if ((addr & PAGE_MASK) != 0) {
memset(buf, 0, sizeof(buf));
@@ -510,7 +523,6 @@ mread(gzFile fp, paddr_t addr, size_t sz
errnum, errstr);
return (0);
}
- rd += ct;
if (write_mem(addr, buf, ct))
return (0);
@@ -538,7 +550,6 @@ mread(gzFile fp, paddr_t addr, size_t sz
errnum, errstr);
return (0);
}
- rd += ct;
if (write_mem(addr, buf, ct))
return (0);
@@ -664,7 +675,6 @@ elf64_exec(gzFile fp, Elf64_Ehdr *elf, u
Elf64_Off off;
int i;
size_t sz;
- int first;
int havesyms;
paddr_t minp = ~0, maxp = 0, pos = 0;
paddr_t offset = marks[MARK_START], shpp, elfp;
@@ -682,7 +692,7 @@ elf64_exec(gzFile fp, Elf64_Ehdr *elf, u
return 1;
}
- for (first = 1, i = 0; i < elf->e_phnum; i++) {
+ for (i = 0; i < elf->e_phnum; i++) {
if (phdr[i].p_type == PT_OPENBSD_RANDOMIZE) {
int m;
@@ -727,8 +737,6 @@ elf64_exec(gzFile fp, Elf64_Ehdr *elf, u
free(phdr);
return 1;
}
-
- first = 0;
}
if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT | COUNT_TEXT))) ||
@@ -802,7 +810,7 @@ elf64_exec(gzFile fp, Elf64_Ehdr *elf, u
if (shp[i].sh_type == SHT_SYMTAB)
havesyms = 1;
- for (first = 1, i = 0; i < elf->e_shnum; i++) {
+ for (i = 0; i < elf->e_shnum; i++) {
if (shp[i].sh_type == SHT_SYMTAB ||
shp[i].sh_type == SHT_STRTAB ||
!strcmp(shstr + shp[i].sh_name, ".debug_line") ||
@@ -827,7 +835,6 @@ elf64_exec(gzFile fp, Elf64_Ehdr *elf, u
shp[i].sh_flags |= SHF_ALLOC;
off += roundup(shp[i].sh_size,
sizeof(Elf64_Addr));
- first = 0;
}
}
if (flags & LOAD_SYM) {
@@ -886,7 +893,6 @@ elf32_exec(gzFile fp, Elf32_Ehdr *elf, u
Elf32_Off off;
int i;
size_t sz;
- int first;
int havesyms;
paddr_t minp = ~0, maxp = 0, pos = 0;
paddr_t offset = marks[MARK_START], shpp, elfp;
@@ -904,7 +910,7 @@ elf32_exec(gzFile fp, Elf32_Ehdr *elf, u
return 1;
}
- for (first = 1, i = 0; i < elf->e_phnum; i++) {
+ for (i = 0; i < elf->e_phnum; i++) {
if (phdr[i].p_type == PT_OPENBSD_RANDOMIZE) {
int m;
@@ -949,8 +955,6 @@ elf32_exec(gzFile fp, Elf32_Ehdr *elf, u
free(phdr);
return 1;
}
-
- first = 0;
}
if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT | COUNT_TEXT))) ||
@@ -1024,7 +1028,7 @@ elf32_exec(gzFile fp, Elf32_Ehdr *elf, u
if (shp[i].sh_type == SHT_SYMTAB)
havesyms = 1;
- for (first = 1, i = 0; i < elf->e_shnum; i++) {
+ for (i = 0; i < elf->e_shnum; i++) {
if (shp[i].sh_type == SHT_SYMTAB ||
shp[i].sh_type == SHT_STRTAB ||
!strcmp(shstr + shp[i].sh_name, ".debug_line")) {
@@ -1048,7 +1052,6 @@ elf32_exec(gzFile fp, Elf32_Ehdr *elf, u
shp[i].sh_flags |= SHF_ALLOC;
off += roundup(shp[i].sh_size,
sizeof(Elf32_Addr));
- first = 0;
}
}
if (flags & LOAD_SYM) {
Index: vm.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/vm.c,v
retrieving revision 1.66
diff -u -p -r1.66 vm.c
--- vm.c 29 Nov 2021 05:17:35 -0000 1.66
+++ vm.c 22 Dec 2021 14:33:55 -0000
@@ -336,7 +336,7 @@ start_vm(struct vmd_vm *vm, int fd)
fatalx("failed to open kernel - exiting");
/* Load kernel image */
- ret = loadfile_elf(fp, vcp, &vrs);
+ ret = loadfile_elf(fp, vcp, &vrs, vmc->vmc_bootdevice);
/*
* Try BIOS as a fallback (only if it was provided as an image