From e1d35789fb12eb82968a1f7337e7869c4785c6e2 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Sun, 1 Nov 2015 22:39:48 +0100 Subject: [PATCH] tools: create partitions table with EMILE driver Signed-off-by: Laurent Vivier --- tools/Makefile | 7 +- tools/emile-mktable.c | 282 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 tools/emile-mktable.c diff --git a/tools/Makefile b/tools/Makefile index 3db5a87..45d382d 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -9,13 +9,13 @@ TOP=$(shell pwd) PROGRAMS = emile-set-cmdline emile-first-tune emile-install \ emile-set-output emile emile-map-set iso9660_ls \ iso9660_cat minigzip read_vmlinuz emile-mkisofs \ - ext2_ls ext2_cat + ext2_ls ext2_cat emile-mktable SOURCES = emile-set-cmdline.c Makefile emile-first-tune.c \ emile-install.c emile-set-output.c emile.c \ emile_scanbus.c emile-map-set.c iso9660_ls.c \ iso9660_cat.c minigzip.c read_vmlinuz.c device.c gzio.c \ - emile-mkisofs.c ext2_ls.c ext2_cat.c + emile-mkisofs.c ext2_ls.c ext2_cat.c emile-mktable.c HEADERS = device.h @@ -53,6 +53,7 @@ minigzip: minigzip.c gzio.c read_vmlinuz: read_vmlinuz.o gzio.o emile-mkisofs: emile-mkisofs.o device.o +emile-mktable: emile-mktable.o device.o install: install -d $(DESTDIR)/$(PREFIX)/sbin/ @@ -63,6 +64,7 @@ install: install emile $(DESTDIR)/$(PREFIX)/sbin/emile install emile-map-set $(DESTDIR)/$(PREFIX)/sbin/emile-map-set install emile-mkisofs $(DESTDIR)/$(PREFIX)/sbin/emile-mkisofs + install emile-mktable $(DESTDIR)/$(PREFIX)/sbin/emile-mktable uninstall: rm -f $(DESTDIR)/$(PREFIX)/sbin/emile-set-cmdline @@ -72,6 +74,7 @@ uninstall: rm -f $(DESTDIR)/$(PREFIX)/sbin/emile rm -f $(DESTDIR)/$(PREFIX)/sbin/emile-map-set rm -f $(DESTDIR)/$(PREFIX)/sbin/emile-mkisofs + rm -f $(DESTDIR)/$(PREFIX)/sbin/emile-mktable dist: @echo TAR tools diff --git a/tools/emile-mktable.c b/tools/emile-mktable.c new file mode 100644 index 0000000..a616274 --- /dev/null +++ b/tools/emile-mktable.c @@ -0,0 +1,282 @@ +/* + * + * (c) 2015 Laurent Vivier + * + * HOWTO create a bootable disk: + * + * emile-mktable -e second/m68k-linux-scsi-driver/apple_driver /dev/sdh + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "device.h" + +#define DRIVER_SIZE (64*1024) + +#define DRIVER_PATH "/lib/emile/apple_driver" + +#define PARTITION_TABLE_LEN 63 +#define DRIVER_BASE (PARTITION_TABLE_LEN + 1) +#define MAP_BLOCK_COUNT 4 /* 4 entries in the table: map, driver, HFS, extra */ +#define EXTRA_BASE (4*1024*1024/512) /* 4 MB */ + +enum { + ARG_NONE = 0, + ARG_HELP ='h', + ARG_EMILEDRIVER = 'e', +}; + +static struct option long_options[] = +{ + {"help", 0, NULL, ARG_HELP }, + {"emiledriver", 1, NULL, ARG_EMILEDRIVER }, + {NULL, 0, NULL, 0 }, +}; + +static void usage(int argc, char** argv) +{ + fprintf(stderr, "Usage %s [FLAGS] disk\n", + argv[0]); + fprintf(stderr, "Create and EMILE bootable disk\n"); + fprintf(stderr, " -h, --help display this text\n"); + fprintf(stderr, " -e, --emiledriver=FILE " + "emiledriver to copy to disk\n"); + fprintf(stderr, "\nbuild: \n%s\n", SIGNATURE); +} + +#define BLOCKSIZE (512) + +static int emile_mktable(char *filename, char *appledriver) +{ + struct DriverDescriptor block0; + struct Partition *map512; + int fd_driver; + unsigned char *driver; + struct stat st; + int driver_size; + int fd; + int i; + unsigned long disk_block_count; + u_int32_t driver_block_count, extra_block_count, hfs_block_count; + int current; + + /* open disk */ + + fd = open(filename, O_WRONLY); + if (fd == -1) { + fprintf(stderr, + "ERROR: Cannot open file %s\n", + filename); + return -1; + } + if (ioctl(fd, BLKGETSIZE, &disk_block_count) == -1) { + fstat(fd, &st); + disk_block_count = (st.st_size + 512 - 1) / 512; + } + + /* read apple driver */ + + fd_driver = open(appledriver, O_RDONLY); + if (fd_driver == -1) + { + fprintf(stderr, "Cannot open %s\n", appledriver); + return -1; + } + fstat(fd_driver, &st); + driver_size = ((st.st_size + DRIVER_SIZE - 1) / DRIVER_SIZE) * + DRIVER_SIZE; + driver = malloc(driver_size); + memset(driver, 0, driver_size); + if (driver == NULL) + { + fprintf(stderr, "Cannot malloc %d bytes\n", driver_size); + return -1; + } + read(fd_driver, driver, st.st_size); + + close(fd_driver); + + /* Driver Descriptor 512 bytes + * Driver Partition Map (for 512 byte blocks) 512 bytes + * Driver Partition N x 512 bytes + * HFS + * Extra + */ + + + /* initialize block 0 with the size of the disk and the number of driver */ + + memset(&block0, 0, sizeof(block0)); + write_short((u_int16_t*)&block0.Sig, DD_SIGNATURE); + write_short((u_int16_t*)&block0.BlkSize, BLOCKSIZE); + write_long((u_int32_t*)&block0.BlkCount, disk_block_count); + write_short((u_int16_t*)&block0.DevType, 1); + write_short((u_int16_t*)&block0.DevId, 1); + write_long((u_int32_t*)&block0.Data, 0); + write_short((u_int16_t*)&block0.DrvrCount, 1); + + /* initialize driver info */ + + write_long((u_int32_t*)&block0.DrvInfo[0].Block, DRIVER_BASE); + write_short((u_int16_t*)&block0.DrvInfo[0].Size, (driver_size + BLOCKSIZE - 1) / BLOCKSIZE); + write_short((u_int16_t*)&block0.DrvInfo[0].Type, kDriverTypeMacSCSI); + + /* initialize partition table */ + + map512 = malloc(PARTITION_TABLE_LEN * 512); + if (map512 == NULL) + { + fprintf(stderr, "Cannot malloc %d bytes\n", + PARTITION_TABLE_LEN * 512); + return -1; + } + + memset(map512, 0, PARTITION_TABLE_LEN * 512); + current = 0; + + /* partition table entry */ + + write_short((u_int16_t*)&map512[current].Sig, MAP_SIGNATURE); + write_long((u_int32_t*)&map512[current].MapBlkCnt, MAP_BLOCK_COUNT); + write_long((u_int32_t*)&map512[current].PyPartStart, 1); + write_long((u_int32_t*)&map512[current].PartBlkCnt, PARTITION_TABLE_LEN); + strncpy(map512[current].PartName, "Apple", 32); + strncpy(map512[current].PartType, APPLE_PARTITION_MAP, 32); + write_long((u_int32_t*)&map512[current].DataCnt, PARTITION_TABLE_LEN); + write_long((u_int32_t*)&map512[current].PartStatus, + kPartitionAUXIsWriteable | kPartitionAUXIsReadable | + kPartitionAUXIsInUse | kPartitionAUXIsAllocated | + kPartitionAUXIsValid ); + current++; + + /* initialize driver partition entry */ + + driver_block_count = (driver_size + 512 - 1) / 512; + write_short((u_int16_t*)&map512[current].Sig, MAP_SIGNATURE); + write_long((u_int32_t*)&map512[current].MapBlkCnt, MAP_BLOCK_COUNT); + write_long((u_int32_t*)&map512[current].PartBlkCnt, driver_block_count); + write_long((u_int32_t*)&map512[current].PyPartStart, DRIVER_BASE); + strncpy(map512[current].PartName, "Macintosh", 32); + strncpy(map512[current].PartType, APPLE_DRIVER_EMILE, 32); + write_long((u_int32_t*)&map512[current].DataCnt, driver_block_count); + write_long((u_int32_t*)&map512[current].PartStatus, kPartitionAUXIsValid | + kPartitionAUXIsAllocated | + kPartitionAUXIsInUse | + kPartitionAUXIsBootValid | + kPartitionAUXIsReadable | + kPartitionAUXIsWriteable | + kPartitionAUXIsBootCodePositionIndependent | + kPartitionIsChainCompatible | + kPartitionIsRealDeviceDriver); + write_long((u_int32_t*)&map512[current].BootSize, st.st_size); + write_long((u_int32_t*)&map512[current].BootCksum, emile_checksum(driver, st.st_size)); + strncpy(map512[current].Processor, "68000", 16); + write_long((u_int32_t*)&map512[current].Pad, kSCSIDriverSignature); + current++; + + /* HFS table entry */ + + hfs_block_count = EXTRA_BASE - (DRIVER_BASE + driver_block_count); + write_short((u_int16_t*)&map512[current].Sig, MAP_SIGNATURE); + write_long((u_int32_t*)&map512[current].MapBlkCnt, MAP_BLOCK_COUNT); + write_long((u_int32_t*)&map512[current].PyPartStart, DRIVER_BASE + driver_block_count); + write_long((u_int32_t*)&map512[current].PartBlkCnt, hfs_block_count); + strncpy(map512[current].PartName, "MacOS", 32); + strncpy(map512[current].PartType, APPLE_HFS, 32); + write_long((u_int32_t*)&map512[current].DataCnt, hfs_block_count); + current++; + + /* extra (free) table entry */ + + extra_block_count = disk_block_count - EXTRA_BASE; + write_short((u_int16_t*)&map512[current].Sig, MAP_SIGNATURE); + write_long((u_int32_t*)&map512[current].MapBlkCnt, MAP_BLOCK_COUNT); + write_long((u_int32_t*)&map512[current].PyPartStart, EXTRA_BASE); + write_long((u_int32_t*)&map512[current].PartBlkCnt, extra_block_count); + strncpy(map512[current].PartName, "Extra", 32); + strncpy(map512[current].PartType, APPLE_FREE, 32); + write_long((u_int32_t*)&map512[current].DataCnt, extra_block_count); + current++; + + /* write block 0*/ + + write(fd, &block0, sizeof(block0)); + + /* write partition table */ + + for (i = 0; i < PARTITION_TABLE_LEN; i++) + { + write(fd, map512 + i, 512); + } + + /* write driver */ + + write(fd, driver, driver_size); + free(driver); + + close(fd); + + return 0; +} + +int main(int argc, char** argv) +{ + int option_index = 0; + char* image = NULL; + char* emiledriver = NULL; + int c; + + while(1) + { + c = getopt_long(argc, argv, "he:c:", + long_options, &option_index); + if (c == -1) + break; + switch(c) + { + case ARG_HELP: + usage(argc, argv); + return 0; + case ARG_EMILEDRIVER: + emiledriver = optarg; + break; + } + } + + if (optind < argc) + image = argv[optind++]; + + if (image == NULL) + { + fprintf(stderr,"ERROR: you must provide a filename to write image\n"); + usage(argc, argv); + return 1; + } + + if (emiledriver == NULL) + emiledriver = DRIVER_PATH; + + + if (emile_mktable(image, emiledriver)) + return 1; + + return 0; +}