tools: create partitions table with EMILE driver

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
Laurent Vivier 2015-11-01 22:39:48 +01:00
parent 7a22506a89
commit e1d35789fb
2 changed files with 287 additions and 2 deletions

View File

@ -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

282
tools/emile-mktable.c Normal file
View File

@ -0,0 +1,282 @@
/*
*
* (c) 2015 Laurent Vivier <Laurent@Vivier.EU>
*
* HOWTO create a bootable disk:
*
* emile-mktable -e second/m68k-linux-scsi-driver/apple_driver /dev/sdh
*
*/
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <libmap.h>
#include <emile.h>
#include <libemile.h>
#include <libiso9660.h>
#include <libstream.h>
#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;
}