Option to create EFI CDROM image

This commit is contained in:
bzt 2022-11-08 19:42:02 +01:00
parent 4da8882887
commit 7798e28f98
4 changed files with 138 additions and 9 deletions

View file

@ -8,4 +8,4 @@ all: $(wildcard examples/*)
@test -f $@/Makefile && make -C $@ all 2>/dev/null @test -f $@/Makefile && make -C $@ all 2>/dev/null
test: test:
qemu-system-x86_64 -sdl -bios $(OVMF) -m 64 -enable-kvm -hda fat:rw:examples qemu-system-x86_64 -bios $(OVMF) -m 64 -enable-kvm -hda fat:rw:examples

View file

@ -31,9 +31,10 @@ programodat `EFI/BOOT/BOOTX64.EFI` néven kell bemásolni a könyvtárba, hogy m
``` ```
POSIX-UEFI utils - efidsk by bztsrc@gitlab MIT POSIX-UEFI utils - efidsk by bztsrc@gitlab MIT
./efidsk [-p] [-s <méret>] bekönyvtár kimenet ./efidsk [-p|-c] [-s <méret>] bekönyvtár kimenet
-p csak a partíciót mentse, GPT nélkül -p csak a partíciót mentse, GPT nélkül
-c EFI CDROM mentése (ISO9660 El Torito no emulation boot catalog)
-s <méret> a partíció méretének megadása megabájtban (alapértelmezetten 33M) -s <méret> a partíció méretének megadása megabájtban (alapértelmezetten 33M)
bekönvtár ennek a könyvtárnak a tartalmából generálja bekönvtár ennek a könyvtárnak a tartalmából generálja
kimenet kimenti lemezképfájl neve kimenet kimenti lemezképfájl neve

View file

@ -31,9 +31,10 @@ compiled file under the given directory as `EFI/BOOT/BOOTX64.EFI` to get it auto
``` ```
POSIX-UEFI utils - efidsk by bztsrc@gitlab MIT POSIX-UEFI utils - efidsk by bztsrc@gitlab MIT
./efidsk [-p] [-s <size>] indir outfile ./efidsk [-p|-c] [-s <size>] indir outfile
-p save only the partition image without GPT -p save only the partition image without GPT
-c save EFI CDROM (ISO9660 El Torito no emulation boot catalog)
-s <size> set the size of partition in megabytes (defaults to 33M) -s <size> set the size of partition in megabytes (defaults to 33M)
indir use the contents of this directory indir use the contents of this directory
outfile output image file name outfile output image file name

View file

@ -50,8 +50,9 @@ guid_t dguid, pguid;
void usage(char *cmd) void usage(char *cmd)
{ {
printf("POSIX-UEFI utils - efidsk by bztsrc@gitlab MIT\r\n\r\n"); printf("POSIX-UEFI utils - efidsk by bztsrc@gitlab MIT\r\n\r\n");
printf("%s [-p] [-s <size>] indir outfile\r\n\r\n", cmd); printf("%s [-p|-c] [-s <size>] indir outfile\r\n\r\n", cmd);
printf(" -p save only the partition image without GPT\r\n"); printf(" -p save only the partition image without GPT\r\n");
printf(" -c save EFI CDROM (ISO9660 El Torito no emulation boot catalog)\r\n");
printf(" -s <size> set the size of partition in megabytes (defaults to 33M)\r\n"); printf(" -s <size> set the size of partition in megabytes (defaults to 33M)\r\n");
printf(" indir use the contents of this directory\r\n"); printf(" indir use the contents of this directory\r\n");
printf(" outfile output image file name\r\n"); printf(" outfile output image file name\r\n");
@ -420,9 +421,25 @@ void writegpt(FILE *f)
char *name; char *name;
if(!gpt) { fprintf(stderr, "efidsk: unable to allocate memory\r\n"); exit(1); } if(!gpt) { fprintf(stderr, "efidsk: unable to allocate memory\r\n"); exit(1); }
memset(gpt, 0, FIRST_PARTITION * 512); memset(gpt, 0, FIRST_PARTITION * 512);
p = gpt + 512;
gpt[0x1FE]=0x55; gpt[0x1FF]=0xAA;
memcpy(gpt+0x1B8, &dguid.Data1, 4); /* WinNT disk id */
/* MBR, EFI System Partition / boot partition. */
gpt[0x1C0-2]=0x80; /* bootable flag */
setint(FIRST_PARTITION+1,gpt+0x1C0); /* start CHS */
gpt[0x1C0+2]=0xC; /* type, LBA FAT32 (0xC) */
setint(fs_len/512,gpt+0x1C0+4); /* end CHS */
setint(FIRST_PARTITION,gpt+0x1C0+6); /* start LBA */
setint(fs_len/512,gpt+0x1C0+10); /* number of sectors */
/* MBR, protective GPT entry */
setint(1,gpt+0x1D0); /* start CHS */
gpt[0x1D0+2]=0xEE; /* type */
setint(FIRST_PARTITION+1,gpt+0x1D0+4); /* end CHS */
setint(1,gpt+0x1D0+6); /* start LBA */
setint(FIRST_PARTITION,gpt+0x1D0+10); /* number of sectors */
/* GPT header */ /* GPT header */
p = gpt + 512;
memcpy(p,"EFI PART",8); /* magic */ memcpy(p,"EFI PART",8); /* magic */
setint(1,p+10); /* revision */ setint(1,p+10); /* revision */
setint(92,p+12); /* size */ setint(92,p+12); /* size */
@ -462,13 +479,119 @@ void writegpt(FILE *f)
free(gpt); free(gpt);
} }
/**
* Write out ISO9660 El Torito "no emulation" Boot Catalog
*/
void setinte(int val, unsigned char *ptr) { char *v=(char*)&val; memcpy(ptr,&val,4); ptr[4]=v[3]; ptr[5]=v[2]; ptr[6]=v[1]; ptr[7]=v[0]; }
void writeetbc(FILE *f)
{
int i;
time_t t;
char isodate[128];
unsigned char *gpt = malloc(FIRST_PARTITION * 512), *iso;
if(!gpt) { fprintf(stderr, "efidsk: unable to allocate memory\r\n"); exit(1); }
memset(gpt, 0, FIRST_PARTITION * 512);
t = time(NULL);
fat_ts = gmtime(&t);
sprintf((char*)&isodate, "%04d%02d%02d%02d%02d%02d00",
fat_ts->tm_year+1900,fat_ts->tm_mon+1,fat_ts->tm_mday,fat_ts->tm_hour,fat_ts->tm_min,fat_ts->tm_sec);
iso = gpt + 16*2048;
/* 16th sector: Primary Volume Descriptor */
iso[0]=1; /* Header ID */
memcpy(&iso[1], "CD001", 5);
iso[6]=1; /* version */
for(i=8;i<72;i++) iso[i]=' ';
memcpy(&iso[40], "EFI CDROM", 9); /* Volume Identifier */
setinte((FIRST_PARTITION*512+fs_len+2047)/2048, &iso[80]);
iso[120]=iso[123]=1; /* Volume Set Size */
iso[124]=iso[127]=1; /* Volume Sequence Number */
iso[129]=iso[130]=8; /* logical blocksize (0x800) */
iso[156]=0x22; /* root directory recordsize */
setinte(20, &iso[158]); /* root directory LBA */
setinte(2048, &iso[166]); /* root directory size */
iso[174]=fat_ts->tm_year; /* root directory create date */
iso[175]=fat_ts->tm_mon+1;
iso[176]=fat_ts->tm_mday;
iso[177]=fat_ts->tm_hour;
iso[178]=fat_ts->tm_min;
iso[179]=fat_ts->tm_sec;
iso[180]=0; /* timezone UTC (GMT) */
iso[181]=2; /* root directory flags (0=hidden,1=directory) */
iso[184]=1; /* root directory number */
iso[188]=1; /* root directory filename length */
for(i=190;i<813;i++) iso[i]=' '; /* Volume data */
memcpy(&iso[318], "POSIX-UEFI <HTTPS://GITLAB.COM/BZTSRC/POSIX-UEFI>", 49);
memcpy(&iso[446], "EFIDSK", 6);
memcpy(&iso[574], "POSIX-UEFI", 11);
for(i=702;i<813;i++) iso[i]=' '; /* file descriptors */
memcpy(&iso[813], &isodate, 16); /* volume create date */
memcpy(&iso[830], &isodate, 16); /* volume modify date */
for(i=847;i<863;i++) iso[i]='0'; /* volume expiration date */
for(i=864;i<880;i++) iso[i]='0'; /* volume shown date */
iso[881]=1; /* filestructure version */
for(i=883;i<1395;i++) iso[i]=' '; /* file descriptors */
/* 17th sector: Boot Record Descriptor */
iso[2048]=0; /* Header ID */
memcpy(&iso[2049], "CD001", 5);
iso[2054]=1; /* version */
memcpy(&iso[2055], "EL TORITO SPECIFICATION", 23);
setinte(19, &iso[2048+71]); /* Boot Catalog LBA */
/* 18th sector: Volume Descritor Terminator */
iso[4096]=0xFF; /* Header ID */
memcpy(&iso[4097], "CD001", 5);
iso[4102]=1; /* version */
/* 19th sector: Boot Catalog */
/* --- UEFI, Validation Entry + Initial/Default Entry + Final --- */
iso[6144]=0x91; /* Header ID, Validation Entry, Final */
iso[6145]=0xEF; /* Platform EFI */
iso[6176]=0x88; /* Bootable, Initial/Default Entry */
iso[6182]=1; /* Sector Count */
setint(FIRST_PARTITION/4, &iso[6184]); /* ESP Start LBA */
/* 20th sector: Root Directory */
/* . */
iso[8192]=0x21 + 1; /* recordsize */
setinte(20, &iso[8194]); /* LBA */
setinte(2048, &iso[8202]); /* size */
iso[8210]=fat_ts->tm_year; /* date */
iso[8211]=fat_ts->tm_mon+1;
iso[8212]=fat_ts->tm_mday;
iso[8213]=fat_ts->tm_hour;
iso[8214]=fat_ts->tm_min;
iso[8215]=fat_ts->tm_sec;
iso[8216]=0; /* timezone UTC (GMT) */
iso[8217]=2; /* flags (0=hidden,1=directory) */
iso[8220]=1; /* serial */
iso[8224]=1; /* filename length */
iso[8225]=0; /* filename '.' */
/* .. */
iso[8226]=0x21 + 1; /* recordsize */
setinte(20, &iso[8228]); /* LBA */
setinte(2048, &iso[8236]); /* size */
iso[8244]=fat_ts->tm_year; /* date */
iso[8245]=fat_ts->tm_mon+1;
iso[8246]=fat_ts->tm_mday;
iso[8247]=fat_ts->tm_hour;
iso[8248]=fat_ts->tm_min;
iso[8249]=fat_ts->tm_sec;
iso[8250]=0; /* timezone UTC (GMT) */
iso[8251]=2; /* flags (0=hidden,1=directory) */
iso[8254]=1; /* serial */
iso[8258]=1; /* filename length */
iso[8259]='\001'; /* filename '..' */
fwrite(gpt, 1, FIRST_PARTITION * 512, f);
fwrite(fs_base, 1, fs_len, f);
free(gpt);
}
/** /**
* Main function * Main function
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *f; FILE *f;
int i, part = 0; int i, part = 0, cdrom = 0;
char *in = NULL, *out = NULL; char *in = NULL, *out = NULL;
/* get random GUIDs */ /* get random GUIDs */
@ -487,6 +610,7 @@ int main(int argc, char **argv)
if(argv[i][0] == '-') { if(argv[i][0] == '-') {
switch(argv[i][1]) { switch(argv[i][1]) {
case 'p': part++; break; case 'p': part++; break;
case 'c': cdrom++; break;
case 's': fat_numclu = atoi(argv[++i]) * 2048; break; case 's': fat_numclu = atoi(argv[++i]) * 2048; break;
default: usage(argv[0]); break; default: usage(argv[0]); break;
} }
@ -509,9 +633,12 @@ int main(int argc, char **argv)
fprintf(stderr, "efidsk: unable to write '%s'\r\n", out); fprintf(stderr, "efidsk: unable to write '%s'\r\n", out);
return 2; return 2;
} }
if(!part) if(!part) {
writegpt(f); if(!cdrom)
else writegpt(f);
else
writeetbc(f);
} else
fwrite(fs_base, 1, fs_len, f); fwrite(fs_base, 1, fs_len, f);
fclose(f); fclose(f);
free(fs_base); free(fs_base);