mirror of
https://github.com/vivier/EMILE.git
synced 2025-04-06 21:37:06 +00:00
First revision
This commit is contained in:
parent
b9cba58847
commit
8b39d7617e
20
libemile/Makefile
Normal file
20
libemile/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
LIBRARY = libemile.a
|
||||
|
||||
OBJS = emile_first_get_param.o emile_first_set_param.o \
|
||||
emile_first_set_param_scsi.o emile_floppy_create_image.o \
|
||||
emile_scsi_create_container.o emile_second_get_cmdline.o \
|
||||
emile_second_get_kernel.o emile_second_get_output.o \
|
||||
emile_second_set_cmdline.o emile_second_set_kernel.o \
|
||||
emile_second_set_kernel_scsi.o emile_second_set_output.o
|
||||
|
||||
HEADERS = emile.h libemile.h emile-first.h
|
||||
|
||||
CFLAGS = -Wall
|
||||
|
||||
all: $(LIBRARY)
|
||||
|
||||
$(LIBRARY): $(OBJS)
|
||||
$(AR) rc $@ $^
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(LIBRARY)
|
69
libemile/bootblock.h
Normal file
69
libemile/bootblock.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* WARNING: remember that m68k is big endian, like powerPC.
|
||||
* i386 is little-endian
|
||||
*/
|
||||
|
||||
#ifndef _BOOTBLOCK_H
|
||||
#define _BOOTBLOCK_H
|
||||
static __attribute__((used)) char* bootblock_header = "$CVSHeader$";
|
||||
#include "../second/glue.h"
|
||||
|
||||
/* first level structure */
|
||||
|
||||
/* BootBlkHdr Structure: "Inside Macintosh: Files", p. 2-57 */
|
||||
|
||||
typedef struct BootBlkHdr BootBlkHdr_t;
|
||||
|
||||
struct BootBlkHdr {
|
||||
u_int16_t ID; /* boot blocks signature */
|
||||
u_int32_t Entry; /* entry point to bootcode */
|
||||
u_int16_t Version; /* boot blocks version number */
|
||||
u_int16_t PageFlags; /* used internally */
|
||||
u_int8_t SysName[16]; /* System filename */
|
||||
u_int8_t ShellName[16]; /* Finder filename */
|
||||
u_int8_t Dbg1Name[16]; /* debugger filename */
|
||||
u_int8_t Dbg2Name[16]; /* debugger filename */
|
||||
u_int8_t ScreenName[16]; /* name of startup screen */
|
||||
u_int8_t HelloName[16]; /* name of startup program */
|
||||
u_int8_t ScrapName[16]; /* name of system scrap file */
|
||||
u_int16_t CntFCBs; /* number of FCBs to allocate */
|
||||
u_int16_t CntEvts; /* number of event queue elements */
|
||||
u_int32_t Heap128K; /* system heap size on 128K Mac */
|
||||
u_int32_t Heap256K; /* used internally */
|
||||
u_int32_t SysHeapSize; /* system heap size on all machines */
|
||||
} __attribute__((packed));
|
||||
|
||||
#define ASSERT_BBH(a) if ( sizeof(BootBlkHdr_t) != 138 ) { a }
|
||||
|
||||
/* EMILE Boot block structure */
|
||||
|
||||
typedef struct eBootBlock eBootBlock_t;
|
||||
|
||||
struct eBootBlock {
|
||||
BootBlkHdr_t boot_block_header;
|
||||
ParamBlockRec_t second_param_block;
|
||||
u_int8_t boot_code[1024 - sizeof(BootBlkHdr_t)
|
||||
- sizeof(ParamBlockRec_t)];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define ASSERT_BB(a) if ( sizeof(eBootBlock_t) != 1024 ) { a }
|
||||
|
||||
#define FLOPPY_SECTOR_SIZE 512
|
||||
#define FIRST_LEVEL_SIZE (FLOPPY_SECTOR_SIZE * 2)
|
||||
|
||||
static inline unsigned long get_size(char* file)
|
||||
{
|
||||
struct stat result;
|
||||
|
||||
stat(file, &result);
|
||||
|
||||
return (result.st_size + FLOPPY_SECTOR_SIZE - 1)
|
||||
/ FLOPPY_SECTOR_SIZE * FLOPPY_SECTOR_SIZE;
|
||||
}
|
||||
#endif
|
71
libemile/emile.h
Normal file
71
libemile/emile.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _EMILE_H
|
||||
#define _EMILE_H
|
||||
static __attribute__((used)) char* emile_header = "$CVSHeader$";
|
||||
#include <endian.h>
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
|
||||
/* nothing to do, because m68k is big endian too */
|
||||
|
||||
static inline u_int16_t read_short(u_int16_t* addr)
|
||||
{
|
||||
return *addr;
|
||||
}
|
||||
|
||||
static inline void write_short(u_int16_t* addr, u_int16_t value)
|
||||
{
|
||||
*addr = value;
|
||||
}
|
||||
|
||||
static inline u_int32_t read_long(u_int32_t* addr)
|
||||
{
|
||||
return *addr;
|
||||
}
|
||||
|
||||
static inline void write_long(u_int32_t* addr, u_int32_t value)
|
||||
{
|
||||
*addr = value;
|
||||
}
|
||||
|
||||
#else /* __BYTE_ORDER == __LITTLE_ENDIAN */
|
||||
|
||||
/* little endian (or unknown), read byte by byte to get it in good order */
|
||||
|
||||
static inline u_int16_t read_short(u_int16_t* addr)
|
||||
{
|
||||
unsigned char* baddr = (unsigned char*)addr;
|
||||
|
||||
return ((u_int16_t)(*baddr) << 8) | (u_int16_t)*(baddr+1);
|
||||
}
|
||||
|
||||
static inline void write_short(u_int16_t* addr, u_int16_t value)
|
||||
{
|
||||
unsigned char* baddr = (unsigned char*)addr;
|
||||
|
||||
*baddr = (unsigned char)(value>>8);
|
||||
*(baddr+1) = (unsigned char)value;
|
||||
}
|
||||
|
||||
static inline u_int32_t read_long(u_int32_t* addr)
|
||||
{
|
||||
u_int16_t* saddr = (u_int16_t*)addr;
|
||||
|
||||
return ((u_int32_t)read_short(saddr) << 16) |
|
||||
(u_int32_t)read_short(saddr+1);;
|
||||
}
|
||||
|
||||
static inline void write_long(u_int32_t* addr, u_int32_t value)
|
||||
{
|
||||
u_int16_t* saddr = (u_int16_t*)addr;
|
||||
|
||||
write_short(saddr, (u_int16_t)(value>>16));
|
||||
write_short(saddr+1, (u_int16_t)value);
|
||||
}
|
||||
#endif
|
||||
#endif
|
39
libemile/emile_first_get_param.c
Normal file
39
libemile/emile_first_get_param.c
Normal file
@ -0,0 +1,39 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "bootblock.h"
|
||||
|
||||
int emile_first_get_param(int fd, int *drive_num, int *file_ref,
|
||||
int *second_offset, int *second_size)
|
||||
{
|
||||
eBootBlock_t firstBlock;
|
||||
int ret;
|
||||
|
||||
ret = read(fd, &firstBlock, sizeof(firstBlock));
|
||||
if (ret != sizeof(firstBlock))
|
||||
return -1;
|
||||
|
||||
if ( strncmp( firstBlock.boot_block_header.SysName+1,
|
||||
"Mac Bootloader", 14) == 0 )
|
||||
{
|
||||
*drive_num = read_short(&firstBlock.second_param_block.ioVRefNum);
|
||||
*file_ref = read_short(&firstBlock.second_param_block.ioRefNum);
|
||||
*second_offset = read_long(&firstBlock.second_param_block.ioPosOffset);
|
||||
*second_size = read_long(&firstBlock.second_param_block.ioReqCount);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
59
libemile/emile_first_set_param.c
Normal file
59
libemile/emile_first_set_param.c
Normal file
@ -0,0 +1,59 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "bootblock.h"
|
||||
|
||||
int emile_first_set_param(int fd, unsigned short tune_mask, int drive_num,
|
||||
int file_ref, int second_offset, int second_size)
|
||||
{
|
||||
eBootBlock_t firstBlock;
|
||||
int ret;
|
||||
off_t location;
|
||||
|
||||
location = lseek(fd, 0, SEEK_CUR);
|
||||
if (location == -1)
|
||||
return -1;
|
||||
|
||||
ret = read(fd, &firstBlock, sizeof(firstBlock));
|
||||
if (ret != sizeof(firstBlock))
|
||||
return -1;
|
||||
|
||||
if ( strncmp( firstBlock.boot_block_header.SysName+1,
|
||||
"Mac Bootloader", 14) == 0 )
|
||||
{
|
||||
if (tune_mask & EMILE_FIRST_TUNE_DRIVE)
|
||||
write_short(&firstBlock.second_param_block.ioVRefNum,
|
||||
drive_num);
|
||||
|
||||
if (tune_mask & EMILE_FIRST_TUNE_OFFSET)
|
||||
write_long(&firstBlock.second_param_block.ioPosOffset,
|
||||
second_offset);
|
||||
|
||||
if (tune_mask & EMILE_FIRST_TUNE_SIZE)
|
||||
write_long(&firstBlock.second_param_block.ioReqCount,
|
||||
second_size);
|
||||
|
||||
ret = lseek(fd, location, SEEK_SET);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
ret = write(fd, &firstBlock, sizeof(firstBlock));
|
||||
if (ret != sizeof(firstBlock))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
87
libemile/emile_first_set_param_scsi.c
Normal file
87
libemile/emile_first_set_param_scsi.c
Normal file
@ -0,0 +1,87 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "libemile.h"
|
||||
|
||||
int emile_first_set_param_scsi(int fd, char *second_name)
|
||||
{
|
||||
int ret;
|
||||
int fd_second;
|
||||
char first[1024];
|
||||
int i;
|
||||
int current;
|
||||
struct emile_container *container;
|
||||
unsigned short max_blocks;
|
||||
unsigned short *first_max_blocks = (unsigned short*)&first[1022];
|
||||
unsigned long *second_size = (unsigned long*)&first[1018];
|
||||
unsigned short *unit_id = (unsigned short*)&first[1016];
|
||||
unsigned short *block_size = (unsigned short*)&first[1014];
|
||||
unsigned short *count;
|
||||
unsigned long *offset;
|
||||
|
||||
ret = read(fd, first, 1024);
|
||||
if (ret == -1)
|
||||
return 1;
|
||||
|
||||
max_blocks = *first_max_blocks / 6;
|
||||
|
||||
container = (struct emile_container*)
|
||||
malloc(sizeof(struct emile_container)
|
||||
+ max_blocks * sizeof(struct emile_block));
|
||||
if (container == NULL)
|
||||
return -1;
|
||||
|
||||
container->max_blocks = max_blocks;
|
||||
fd_second = open(second_name, O_RDONLY);
|
||||
if (fd_second == -1)
|
||||
return -1;
|
||||
|
||||
ret = emile_scsi_create_container(fd_second, container);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
close(fd_second);
|
||||
|
||||
*unit_id = container->unit_id;
|
||||
*block_size = container->block_size;
|
||||
|
||||
*second_size = 0;
|
||||
current = 1014;
|
||||
for(i = 0; i < max_blocks - 1; i++)
|
||||
{
|
||||
current -= 2;
|
||||
count = (short*)(&first[current]);
|
||||
*count = container->blocks[i].count;
|
||||
if (container->blocks[i].count == 0)
|
||||
break;
|
||||
current -= 4;
|
||||
offset = (long*)(&first[current]);
|
||||
*offset = container->blocks[i].offset;
|
||||
(*second_size) += container->blocks[i].count;
|
||||
}
|
||||
/* mark end of blocks list */
|
||||
current -= 2;
|
||||
count = (short*)(&first[current]);
|
||||
*count = 0;
|
||||
/* set second level size */
|
||||
(*second_size) *= container->block_size;
|
||||
|
||||
ret = lseek(fd, 0, SEEK_SET);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
ret = write(fd, first, 1024);
|
||||
if (ret == -1)
|
||||
return 1;
|
||||
|
||||
return ret;
|
||||
}
|
205
libemile/emile_floppy_create_image.c
Normal file
205
libemile/emile_floppy_create_image.c
Normal file
@ -0,0 +1,205 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "bootblock.h"
|
||||
|
||||
static int copy_file(int fd, char* file)
|
||||
{
|
||||
int source;
|
||||
int size_read;
|
||||
int size_written;
|
||||
int total;
|
||||
static char buffer[FLOPPY_SECTOR_SIZE];
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
source = open(file, O_RDONLY);
|
||||
if (source < 0)
|
||||
{
|
||||
close(source);
|
||||
return -1;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
for(;;)
|
||||
{
|
||||
size_read = read(source, buffer, FLOPPY_SECTOR_SIZE);
|
||||
if (size_read == FLOPPY_SECTOR_SIZE)
|
||||
{
|
||||
size_written = write(fd, buffer, FLOPPY_SECTOR_SIZE);
|
||||
total += size_written;
|
||||
if (size_written != FLOPPY_SECTOR_SIZE)
|
||||
{
|
||||
close(source);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size_read == 0)
|
||||
break;
|
||||
|
||||
memset(buffer + size_read, 0, FLOPPY_SECTOR_SIZE - size_read);
|
||||
size_written = write(fd, buffer, FLOPPY_SECTOR_SIZE);
|
||||
total += size_written;
|
||||
if (size_written != FLOPPY_SECTOR_SIZE)
|
||||
{
|
||||
close(source);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(source);
|
||||
return total;
|
||||
}
|
||||
|
||||
static int pad_image(int fd, int size)
|
||||
{
|
||||
static char buffer[FLOPPY_SECTOR_SIZE];
|
||||
int size_written;
|
||||
int total;
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
if (size % FLOPPY_SECTOR_SIZE) {
|
||||
fprintf(stderr,
|
||||
"WARNING: pad size is not a multiple of sector size\n");
|
||||
}
|
||||
|
||||
memset(buffer, 0, FLOPPY_SECTOR_SIZE);
|
||||
total = 0;
|
||||
while (size > 0) {
|
||||
size_written = write(fd, buffer, FLOPPY_SECTOR_SIZE);
|
||||
total += size_written;
|
||||
if (size_written != FLOPPY_SECTOR_SIZE) {
|
||||
return total;
|
||||
}
|
||||
size -= size_written;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static int aggregate(int fd, char* first_level, char* second_level, char* kernel_image, char* ramdisk)
|
||||
{
|
||||
int ret;
|
||||
int total;
|
||||
|
||||
ret = copy_file(fd, first_level);
|
||||
if (ret < 0)
|
||||
return 6;
|
||||
total = ret;
|
||||
|
||||
ret = copy_file(fd, second_level);
|
||||
if (ret < 0)
|
||||
return 6;
|
||||
total += ret;
|
||||
|
||||
if (kernel_image != NULL)
|
||||
{
|
||||
ret = copy_file(fd, kernel_image);
|
||||
if (ret < 0)
|
||||
return 6;
|
||||
total += ret;
|
||||
}
|
||||
|
||||
if (ramdisk != NULL)
|
||||
{
|
||||
ret = copy_file(fd, ramdisk);
|
||||
if (ret < 0)
|
||||
return 6;
|
||||
total += ret;
|
||||
}
|
||||
|
||||
ret = pad_image(fd, 1474560 - total);
|
||||
if (ret < 0)
|
||||
return 6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emile_floppy_create_image(char* first_level, char* second_level,
|
||||
char* kernel_image, char* ramdisk,
|
||||
unsigned long buffer_size, char* image)
|
||||
{
|
||||
int ret;
|
||||
int fd;
|
||||
unsigned int second_level_size;
|
||||
|
||||
if (image == NULL)
|
||||
return -1;
|
||||
|
||||
fd = open(image, O_RDWR|O_CREAT|O_TRUNC,
|
||||
S_IRUSR| S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
/* aggregating files: first, second, kernel, ramdisk */
|
||||
|
||||
if (first_level == NULL)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (second_level == NULL)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (kernel_image == NULL)
|
||||
fprintf(stderr, "WARNING: kernel image file not defined\n");
|
||||
|
||||
ret = aggregate(fd, first_level, second_level, kernel_image, ramdisk);
|
||||
if (ret != 0)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set first level info */
|
||||
|
||||
ret = emile_first_set_param(fd, EMILE_FIRST_TUNE_DRIVE |
|
||||
EMILE_FIRST_TUNE_OFFSET|
|
||||
EMILE_FIRST_TUNE_SIZE,
|
||||
1, -5,
|
||||
FIRST_LEVEL_SIZE,
|
||||
second_level_size);
|
||||
if (ret != 0)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set second level info */
|
||||
|
||||
ret = emile_second_set_kernel(fd, kernel_image,
|
||||
FIRST_LEVEL_SIZE + get_size(second_level),
|
||||
buffer_size, ramdisk);
|
||||
if (ret != 0)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
199
libemile/emile_scsi_create_container.c
Normal file
199
libemile/emile_scsi_create_container.c
Normal file
@ -0,0 +1,199 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <scsi/scsi.h>
|
||||
|
||||
#include "libemile.h"
|
||||
|
||||
#define MAJOR_SD 8 /* SCSI disks */
|
||||
|
||||
struct scsi_id {
|
||||
int dev;
|
||||
int host_unique_id;
|
||||
};
|
||||
|
||||
static int get_scsi_path(int fd, unsigned char *host, unsigned char *channel,
|
||||
unsigned char *pun, unsigned char *lun)
|
||||
{
|
||||
int ret;
|
||||
struct scsi_id path;
|
||||
|
||||
ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &path);
|
||||
|
||||
*host = path.dev >> 24;
|
||||
*channel = path.dev >> 16;
|
||||
*lun = path.dev >> 8;
|
||||
*pun = path.dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_device_info(int device, int *id, unsigned long *first_block,
|
||||
int *block_size)
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
char dev_name[16];
|
||||
int major;
|
||||
int minor;
|
||||
struct hd_geometry geom;
|
||||
unsigned char host;
|
||||
unsigned char channel;
|
||||
unsigned char pun;
|
||||
unsigned char lun;
|
||||
|
||||
major = (device >> 8) & 0x0F; /* major number = driver id */
|
||||
minor = device & 0xFF; /* minor number = disk id */
|
||||
switch(major)
|
||||
{
|
||||
case MAJOR_SD: /* SCSI disks */
|
||||
sprintf(dev_name, "/dev/sd%c%d", 'a' + (minor >> 4),
|
||||
minor & 0x0F);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown device major number %d\n", major);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = open(dev_name, O_RDONLY);
|
||||
if (fd == 1) {
|
||||
fprintf(stderr, "Cannot open device %s (%s)\n", dev_name,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
ret = get_scsi_path(fd, &host, &channel, &pun, &lun);
|
||||
*id = pun;
|
||||
|
||||
ret = ioctl(fd, HDIO_GETGEO, &geom);
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: ioctl(HDIO_GETGEO) fails: %s",
|
||||
dev_name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#if 0 /* BLKSSZGET is buggy on my m68k 2.2.27-pre2 kernel */
|
||||
ret = ioctl(fd, BLKSSZGET, block_size);
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: ioctl(BLKSSZGET) fails: %s",
|
||||
dev_name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
*block_size = 512;
|
||||
#endif
|
||||
*first_block = geom.start;
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ADD_BLOCK(a, b) \
|
||||
container->blocks[current].offset = (a); \
|
||||
container->blocks[current].count = (b); \
|
||||
current++; \
|
||||
if (current > container->max_blocks) \
|
||||
{ \
|
||||
fprintf(stderr, "Container overflow\n");\
|
||||
return -1; \
|
||||
}
|
||||
|
||||
int emile_scsi_create_container(int fd, struct emile_container* container)
|
||||
{
|
||||
int ret;
|
||||
struct stat st;
|
||||
int id;
|
||||
unsigned long first_block;
|
||||
int sector_size;
|
||||
int block_size;
|
||||
int sectors_per_block;
|
||||
int current;
|
||||
int logical;
|
||||
int physical;
|
||||
int last_physical;
|
||||
int num_blocks;
|
||||
int zone;
|
||||
int aggregate;
|
||||
int dev;
|
||||
|
||||
ret = fstat(fd, &st);
|
||||
if (ret == -1) {
|
||||
perror("stat()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev = S_ISREG(st.st_mode) ? st.st_dev : st.st_rdev;
|
||||
|
||||
ret = get_device_info(dev, &id, &first_block, §or_size);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
container->unit_id = (u_int16_t)id;
|
||||
container->block_size = (u_int16_t)sector_size;
|
||||
|
||||
/* get filesystem block size */
|
||||
|
||||
ret = ioctl(fd, FIGETBSZ, &block_size);
|
||||
if (ret != 0) {
|
||||
perror("ioctl(FIGETBSZ)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sectors_per_block = block_size / sector_size;
|
||||
|
||||
/* get first physical block */
|
||||
|
||||
last_physical = 0;
|
||||
ret = ioctl(fd, FIBMAP, &last_physical);
|
||||
if (ret != 0) {
|
||||
perror("ioctl(FIBMAP)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
zone = last_physical;
|
||||
aggregate = 1;
|
||||
|
||||
/* seek all physical blocks */
|
||||
|
||||
num_blocks = (st.st_size + st.st_blksize - 1) / st.st_blksize;
|
||||
current = 0;
|
||||
for (logical = 1; logical < num_blocks; logical++) {
|
||||
physical = logical;
|
||||
ret = ioctl(fd, FIBMAP, &physical);
|
||||
if (ret != 0)
|
||||
break;
|
||||
if (physical == last_physical + 1) {
|
||||
aggregate++;
|
||||
} else {
|
||||
ADD_BLOCK(first_block + zone * sectors_per_block,
|
||||
aggregate * sectors_per_block);
|
||||
zone = physical;
|
||||
aggregate = 1;
|
||||
}
|
||||
last_physical = physical;
|
||||
}
|
||||
|
||||
ADD_BLOCK(first_block + zone * sectors_per_block,
|
||||
aggregate * sectors_per_block);
|
||||
|
||||
/* end of list */
|
||||
|
||||
ADD_BLOCK(0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
35
libemile/emile_second_get_cmdline.c
Normal file
35
libemile/emile_second_get_cmdline.c
Normal file
@ -0,0 +1,35 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "../second/head.h"
|
||||
|
||||
int emile_second_set_cmdline(int fd, char* cmdline)
|
||||
{
|
||||
emile_l2_header_t header;
|
||||
int ret;
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
if (!EMILE_COMPAT(EMILE_02_SIGNATURE, read_long(&header.signature)))
|
||||
{
|
||||
fprintf(stderr, "Bad Header signature\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(cmdline, header.command_line, 256);
|
||||
|
||||
return 0;
|
||||
}
|
34
libemile/emile_second_get_kernel.c
Normal file
34
libemile/emile_second_get_kernel.c
Normal file
@ -0,0 +1,34 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
|
||||
int emile_second_get_kernel(int fd, u_int32_t *kernel_offset,
|
||||
u_int32_t *kernel_image_size,
|
||||
u_int32_t *kernel_size, u_int32_t *ramdisk_offset,
|
||||
u_int32_t *ramdisk_size)
|
||||
{
|
||||
emile_l2_header_t header;
|
||||
int ret;
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
*kernel_offset = read_long(&header.kernel_image_offset);
|
||||
*kernel_image_size = read_long(&header.kernel_image_size);
|
||||
*kernel_size = read_long(&header.kernel_size);
|
||||
*ramdisk_offset = read_long(&header.ramdisk_offset);
|
||||
*ramdisk_size = read_long(&header.ramdisk_size);
|
||||
|
||||
return 0;
|
||||
}
|
50
libemile/emile_second_get_output.c
Normal file
50
libemile/emile_second_get_output.c
Normal file
@ -0,0 +1,50 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "../second/head.h"
|
||||
|
||||
int emile_second_get_output(int fd, u_int32_t *console_mask,
|
||||
u_int32_t *bitrate0, int *datasize0,
|
||||
int *parity0, int *stopbits0,
|
||||
u_int32_t *bitrate1, int *datasize1,
|
||||
int *parity1, int *stopbits1,
|
||||
int *gestaltid)
|
||||
{
|
||||
emile_l2_header_t header;
|
||||
int ret;
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
if (!EMILE_COMPAT(EMILE_03_SIGNATURE, read_long(&header.signature)))
|
||||
{
|
||||
fprintf(stderr, "Bad Header signature\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*console_mask = read_long(&header.console_mask);
|
||||
*bitrate0 = read_long(&header.serial0_bitrate);
|
||||
*datasize0 = header.serial0_datasize;
|
||||
*parity0 = header.serial0_parity;
|
||||
*stopbits0 = header.serial0_stopbits;
|
||||
*bitrate1 = read_long(&header.serial1_bitrate);
|
||||
*datasize1 = header.serial1_datasize;
|
||||
*parity1 = header.serial1_parity;
|
||||
*stopbits1 = header.serial1_stopbits;
|
||||
|
||||
*gestaltid = read_long(&header.gestaltID);
|
||||
|
||||
return 0;
|
||||
}
|
49
libemile/emile_second_set_cmdline.c
Normal file
49
libemile/emile_second_set_cmdline.c
Normal file
@ -0,0 +1,49 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "../second/head.h"
|
||||
|
||||
int emile_second_set_cmdline(int fd, char* cmdline)
|
||||
{
|
||||
emile_l2_header_t header;
|
||||
off_t location;
|
||||
int ret;
|
||||
|
||||
location = lseek(fd, 0, SEEK_CUR);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
if (!EMILE_COMPAT(EMILE_02_SIGNATURE, read_long(&header.signature)))
|
||||
{
|
||||
fprintf(stderr, "Bad Header signature\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(header.command_line, cmdline, 256);
|
||||
header.command_line[255] = 0;
|
||||
|
||||
ret = lseek(fd, location, SEEK_SET);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
ret = write(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
62
libemile/emile_second_set_kernel.c
Normal file
62
libemile/emile_second_set_kernel.c
Normal file
@ -0,0 +1,62 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "bootblock.h"
|
||||
|
||||
int emile_second_set_kernel(int fd, char *kernel_image,
|
||||
u_int32_t kernel_offset,
|
||||
u_int32_t buffer_size, char* ramdisk)
|
||||
{
|
||||
emile_l2_header_t header;
|
||||
int ret;
|
||||
off_t location;
|
||||
|
||||
location = lseek(fd, 0, SEEK_CUR);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
if (kernel_image != NULL)
|
||||
{
|
||||
write_long(&header.kernel_image_offset, kernel_offset);
|
||||
write_long(&header.kernel_image_size, get_size(kernel_image));
|
||||
}
|
||||
|
||||
write_long(&header.kernel_size, buffer_size);
|
||||
|
||||
if (ramdisk == NULL)
|
||||
{
|
||||
write_long(&header.ramdisk_offset, 0);
|
||||
write_long(&header.ramdisk_size, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_long(&header.ramdisk_offset,
|
||||
read_long(&header.kernel_image_offset) +
|
||||
read_long(&header.kernel_image_size));
|
||||
write_long(&header.ramdisk_size, get_size(ramdisk));
|
||||
}
|
||||
|
||||
ret = lseek(fd, location, SEEK_SET);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
ret = write(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
102
libemile/emile_second_set_kernel_scsi.c
Normal file
102
libemile/emile_second_set_kernel_scsi.c
Normal file
@ -0,0 +1,102 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
|
||||
int emile_second_set_kernel_scsi(int fd, char *kernel_name)
|
||||
{
|
||||
int fd_kernel;
|
||||
int ret;
|
||||
emile_l2_header_t header;
|
||||
off_t container_offset;
|
||||
struct emile_container *container;
|
||||
int max_blocks;
|
||||
int i;
|
||||
unsigned long kernel_image_size;
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
if (!EMILE_COMPAT(EMILE_04_SIGNATURE, read_long(&header.signature)))
|
||||
return -1;
|
||||
|
||||
container_offset = read_long(&header.kernel_image_offset);
|
||||
if (container_offset == 0)
|
||||
return -1;
|
||||
|
||||
ret = lseek(fd, container_offset, SEEK_SET);
|
||||
if (ret != container_offset)
|
||||
return -1;
|
||||
|
||||
container = (struct emile_container*)
|
||||
malloc(sizeof(struct emile_container));
|
||||
if (container == NULL)
|
||||
return -1;
|
||||
|
||||
ret = read(fd, container, sizeof(struct emile_container));
|
||||
if (ret != sizeof(struct emile_container))
|
||||
return -1;
|
||||
|
||||
max_blocks = container->max_blocks;
|
||||
|
||||
free(container);
|
||||
container = (struct emile_container*)
|
||||
malloc(sizeof(struct emile_container)
|
||||
+ max_blocks * sizeof(struct emile_block));
|
||||
if (container == NULL)
|
||||
return -1;
|
||||
|
||||
container->max_blocks = max_blocks;
|
||||
fd_kernel = open(kernel_name, O_RDONLY);
|
||||
if (fd_kernel == -1)
|
||||
return -1;
|
||||
|
||||
ret = emile_scsi_create_container(fd_kernel, container);
|
||||
if (ret != 0)
|
||||
return 10;
|
||||
close(fd_kernel);
|
||||
|
||||
kernel_image_size = 0;
|
||||
for(i = 0; i < max_blocks; i++)
|
||||
{
|
||||
if (container->blocks[i].count == 0)
|
||||
break;
|
||||
kernel_image_size += container->blocks[i].count;
|
||||
}
|
||||
kernel_image_size *= container->block_size;
|
||||
|
||||
ret = lseek(fd, container_offset, SEEK_SET);
|
||||
if (ret != container_offset)
|
||||
return -1;
|
||||
|
||||
ret = write(fd, container, sizeof(struct emile_container)
|
||||
+ max_blocks * sizeof(struct emile_block));
|
||||
if (ret != sizeof(struct emile_container)
|
||||
+ max_blocks * sizeof(struct emile_block))
|
||||
return -1;
|
||||
|
||||
ret = lseek(fd, 0, SEEK_SET);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
header.kernel_image_size = kernel_image_size;
|
||||
|
||||
ret = write(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
80
libemile/emile_second_set_output.c
Normal file
80
libemile/emile_second_set_output.c
Normal file
@ -0,0 +1,80 @@
|
||||
static __attribute__((used)) char* rcsid = "$CVSHeader$";
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libemile.h"
|
||||
#include "emile.h"
|
||||
#include "../second/head.h"
|
||||
|
||||
int emile_second_set_output(int fd,
|
||||
u_int32_t enable_mask, u_int32_t disable_mask,
|
||||
u_int32_t bitrate0, int datasize0,
|
||||
int parity0, int stopbits0,
|
||||
u_int32_t bitrate1, int datasize1,
|
||||
int parity1, int stopbits1, int gestaltid)
|
||||
{
|
||||
emile_l2_header_t header;
|
||||
off_t location;
|
||||
int ret;
|
||||
|
||||
location = lseek(fd, 0, SEEK_CUR);
|
||||
if (location == -1)
|
||||
return location;
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
if (!EMILE_COMPAT(EMILE_03_SIGNATURE, read_long(&header.signature)))
|
||||
{
|
||||
fprintf(stderr, "Bad Header signature\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
header.console_mask |= enable_mask;
|
||||
header.console_mask &= ~disable_mask;
|
||||
|
||||
if (bitrate0)
|
||||
header.serial0_bitrate = bitrate0;
|
||||
if (bitrate1)
|
||||
header.serial1_bitrate = bitrate1;
|
||||
|
||||
if (datasize0 != -1)
|
||||
header.serial0_datasize = datasize0;
|
||||
if (datasize1 != -1)
|
||||
header.serial1_datasize = datasize1;
|
||||
|
||||
if (stopbits0 != -1)
|
||||
header.serial0_stopbits = stopbits0;
|
||||
if (stopbits1 != -1)
|
||||
header.serial1_stopbits = stopbits1;
|
||||
|
||||
if (parity0 != -1)
|
||||
header.serial0_parity = parity0;
|
||||
if (parity1 != -1)
|
||||
header.serial1_parity = parity1;
|
||||
|
||||
header.gestaltID = gestaltid; /* 0 means unset ... */
|
||||
|
||||
ret = lseek(fd, location, SEEK_SET);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("Cannot go to buffer offset");
|
||||
close(fd);
|
||||
return 8;
|
||||
}
|
||||
|
||||
ret = write(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
51
libemile/libemile.h
Normal file
51
libemile/libemile.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LIBEMILE_H
|
||||
#define _LIBEMILE_H
|
||||
|
||||
static __attribute__((used)) char* libemile_header = "$CVSHeader$";
|
||||
|
||||
#define SCSI_SUPPORT
|
||||
|
||||
#include "../second/head.h"
|
||||
|
||||
#define EMILE_FIRST_TUNE_DRIVE 0x0001
|
||||
#define EMILE_FIRST_TUNE_OFFSET 0x0002
|
||||
#define EMILE_FIRST_TUNE_SIZE 0x0004
|
||||
|
||||
extern int emile_first_set_param(int fd, unsigned short tune_mask,
|
||||
int drive_num, int file_ref,
|
||||
int second_offset, int second_size);
|
||||
extern int emile_first_get_param(int fd, int *drive_num, int *file_ref,
|
||||
int *second_offset, int *second_size);
|
||||
extern int emile_first_set_param_scsi(int fd, char *second_name);
|
||||
extern int emile_second_get_output(int fd, unsigned int *console_mask,
|
||||
unsigned int *bitrate0, int *datasize0,
|
||||
int *parity0, int *stopbits0,
|
||||
unsigned int *bitrate1, int *datasize1,
|
||||
int *parity1, int *stopbits1,
|
||||
int *gestaltid);
|
||||
extern int emile_second_set_output(int fd,
|
||||
unsigned int enable_mask,
|
||||
unsigned int disable_mask,
|
||||
unsigned int bitrate0, int datasize0,
|
||||
int parity0, int stopbits0,
|
||||
unsigned int bitrate1, int datasize1,
|
||||
int parity1, int stopbits1, int gestaltid);
|
||||
extern int emile_second_set_cmdline(int fd, char* cmdline);
|
||||
extern int emile_second_get_cmdline(int fd, char* cmdline);
|
||||
extern int emile_second_set_kernel(int fd, char *kernel_image,
|
||||
unsigned int kernel_offset,
|
||||
unsigned int buffer_size, char* ramdisk);
|
||||
extern int emile_second_get_kernel(int fd, unsigned int *kernel_offset,
|
||||
unsigned int *kernel_image_size,
|
||||
unsigned int *buffer_size,
|
||||
unsigned int *ramdisk_offset,
|
||||
unsigned int *ramdisk_size);
|
||||
extern int emile_scsi_create_container(int fd,
|
||||
struct emile_container* container);
|
||||
#endif
|
66
libemile/partition.h
Normal file
66
libemile/partition.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PARTITION_H
|
||||
#define _PARTITION_H
|
||||
static __attribute__((used)) char* partition_header = "$CVSHeader$";
|
||||
|
||||
enum {
|
||||
kPartitionAUXIsValid= 0x00000001,
|
||||
kPartitionAUXIsAllocated = 0x00000002,
|
||||
kPartitionAUXIsInUse= 0x00000004,
|
||||
kPartitionAUXIsBootValid = 0x00000008,
|
||||
kPartitionAUXIsReadable = 0x00000010,
|
||||
kPartitionAUXIsWriteable = 0x00000020,
|
||||
kPartitionAUXIsBootCodePositionIndependent = 0x00000040,
|
||||
|
||||
kPartitionIsMountedAtStartup = 0x40000000,
|
||||
kPartitionIsStartup = 0x80000000,
|
||||
|
||||
kPartitionIsChainCompatible = 0x00000100,
|
||||
kPartitionIsRealDeviceDriver = 0x00000200,
|
||||
kPartitionCanChainToNext = 0x00000400,
|
||||
};
|
||||
|
||||
struct Block0 {
|
||||
int16_t Sig;
|
||||
int16_t BlkSize;
|
||||
int32_t BlkCount;
|
||||
int16_t DevType;
|
||||
int16_t DevId;
|
||||
int32_t Data;
|
||||
int16_t DrvrCount;
|
||||
int32_t Block;
|
||||
int16_t Size;
|
||||
int16_t Type;
|
||||
int16_t Pad[243];
|
||||
} __attribute__((packed));
|
||||
#define ASSERT_B0(a) if ( sizeof(struct Block0) != 512 ) { a }
|
||||
|
||||
struct Partition {
|
||||
int16_t Sig;
|
||||
int16_t SigPad;
|
||||
int32_t MapBlkCnt;
|
||||
int32_t PyPartStart;
|
||||
int32_t PartBlkCnt;
|
||||
char PartName[32];
|
||||
char PartType[32];
|
||||
int32_t LgDataStart;
|
||||
int32_t DataCnt;
|
||||
int32_t PartStatus;
|
||||
int32_t LgBootStart;
|
||||
int32_t BootSize;
|
||||
int32_t BootAddr;
|
||||
int32_t BootAddr2;
|
||||
int32_t BootEntry;
|
||||
int32_t BootEntry2;
|
||||
int32_t BootCksum;
|
||||
char Processor[16];
|
||||
int16_t Pad[188];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define ASSERT_P(a) if ( sizeof(struct Partition) != 512 ) { a }
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user