mirror of
https://github.com/vivier/EMILE.git
synced 2024-12-22 10:29:31 +00:00
first revision
This commit is contained in:
parent
09ef8c96cf
commit
048b48b0e3
409
tools/emile-install.c
Normal file
409
tools/emile-install.c
Normal file
@ -0,0 +1,409 @@
|
||||
/*
|
||||
*
|
||||
* (c) 2004 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "emile.h"
|
||||
#include "emile-first.h"
|
||||
#include "emile-second.h"
|
||||
|
||||
static void usage(int argc, char** argv)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s -f <first level> -s <second level> -i <kernel image> -r <ramdisk> -b <buffer size> <image>\n", argv[0]);
|
||||
}
|
||||
|
||||
static unsigned long get_size(char* file)
|
||||
{
|
||||
struct stat result;
|
||||
|
||||
stat(file, &result);
|
||||
|
||||
return (result.st_size + SECTOR_SIZE - 1) / SECTOR_SIZE * SECTOR_SIZE;
|
||||
}
|
||||
|
||||
static int second_tune(int fd, char* second_level, char *kernel_image, unsigned buffer_size, char* ramdisk)
|
||||
{
|
||||
emile_l2_header_t header;
|
||||
int ret;
|
||||
|
||||
ret = lseek(fd, FIRST_LEVEL_SIZE, SEEK_SET);
|
||||
if (ret == -1)
|
||||
{
|
||||
close(fd);
|
||||
return 3;
|
||||
}
|
||||
|
||||
ret = read(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
{
|
||||
close(fd);
|
||||
return 7;
|
||||
}
|
||||
|
||||
write_long(&header.kernel_image_offset,
|
||||
FIRST_LEVEL_SIZE + get_size(second_level));
|
||||
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));
|
||||
}
|
||||
printf("Setting second level info: \n");
|
||||
printf("kernel offset %ld, kernel size %ld, buffer size %ld\n",
|
||||
read_long(&header.kernel_image_offset),
|
||||
read_long(&header.kernel_image_size),
|
||||
read_long(&header.kernel_size));
|
||||
printf("ramdisk offset %ld, ramdisk size %ld\n",
|
||||
read_long(&header.ramdisk_offset),
|
||||
read_long(&header.ramdisk_size));
|
||||
|
||||
ret = lseek(fd, FIRST_LEVEL_SIZE, SEEK_SET);
|
||||
if (ret == -1)
|
||||
{
|
||||
close(fd);
|
||||
return 3;
|
||||
}
|
||||
|
||||
ret = write(fd, &header, sizeof(header));
|
||||
if (ret != sizeof(header))
|
||||
{
|
||||
close(fd);
|
||||
return 7;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int first_tune(int fd, char* second_level)
|
||||
{
|
||||
int ret;
|
||||
eBootBlock_t firstBlock;
|
||||
|
||||
ret = lseek(fd, 0, SEEK_SET);
|
||||
if (ret == -1)
|
||||
return 9;
|
||||
|
||||
ret = read(fd, &firstBlock, sizeof(firstBlock));
|
||||
if (ret != sizeof(firstBlock))
|
||||
return 10;
|
||||
|
||||
/* drive number */
|
||||
|
||||
write_short(&firstBlock.second_param_block.ioVRefNum, 1);
|
||||
|
||||
/* second offset */
|
||||
|
||||
write_long(&firstBlock.second_param_block.ioPosOffset, FIRST_LEVEL_SIZE);
|
||||
|
||||
/* second size */
|
||||
|
||||
write_long(&firstBlock.second_param_block.ioReqCount, get_size(second_level));
|
||||
|
||||
printf(
|
||||
"Setting second level position to: drive %d, offset %ld, size %ld\n",
|
||||
read_short(&firstBlock.second_param_block.ioVRefNum),
|
||||
read_long(&firstBlock.second_param_block.ioPosOffset),
|
||||
read_long(&firstBlock.second_param_block.ioReqCount));
|
||||
|
||||
/* writing */
|
||||
|
||||
ret = lseek(fd, 0, SEEK_SET);
|
||||
if (ret == -1)
|
||||
return 11;
|
||||
|
||||
ret = write(fd, &firstBlock, sizeof(firstBlock));
|
||||
if (ret != sizeof(firstBlock))
|
||||
if (ret != sizeof(firstBlock))
|
||||
return 12;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_file(int fd, char* file)
|
||||
{
|
||||
int source;
|
||||
int size_read;
|
||||
int size_written;
|
||||
int total;
|
||||
static char buffer[SECTOR_SIZE];
|
||||
|
||||
if (fd < 0)
|
||||
return 7;
|
||||
|
||||
source = open(file, O_RDONLY);
|
||||
if (source < 0)
|
||||
{
|
||||
close(source);
|
||||
return 7;
|
||||
}
|
||||
|
||||
printf("Copying %s: ", file);
|
||||
total = 0;
|
||||
for(;;)
|
||||
{
|
||||
size_read = read(source, buffer, SECTOR_SIZE);
|
||||
if (size_read == SECTOR_SIZE)
|
||||
{
|
||||
size_written = write(fd, buffer, SECTOR_SIZE);
|
||||
total += size_written;
|
||||
if (size_written != SECTOR_SIZE)
|
||||
{
|
||||
close(source);
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size_read == 0)
|
||||
break;
|
||||
|
||||
memset(buffer + size_read, 0, SECTOR_SIZE - size_read);
|
||||
size_written = write(fd, buffer, SECTOR_SIZE);
|
||||
total += size_written;
|
||||
if (size_written != SECTOR_SIZE)
|
||||
{
|
||||
close(source);
|
||||
return 8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d bytes\n", total);
|
||||
close(source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aggregate(int fd, char* first_level, char* second_level, char* kernel_image, char* ramdisk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = copy_file(fd, first_level);
|
||||
if (ret != 0)
|
||||
return 6;
|
||||
ret = copy_file(fd, second_level);
|
||||
if (ret != 0)
|
||||
return 6;
|
||||
ret = copy_file(fd, kernel_image);
|
||||
if (ret != 0)
|
||||
return 6;
|
||||
if (ramdisk != NULL)
|
||||
{
|
||||
ret = copy_file(fd, ramdisk);
|
||||
if (ret != 0)
|
||||
return 6;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_image(char* first_level, char* second_level, char* kernel_image,
|
||||
char* ramdisk, unsigned long buffer_size, char* image)
|
||||
{
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
if (image == NULL)
|
||||
{
|
||||
fprintf(stderr, "Image file not defined\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
printf("Creating %s\n", image);
|
||||
fd = open(image, O_RDWR|O_CREAT|O_TRUNC,
|
||||
S_IRUSR| S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
|
||||
if (fd == -1)
|
||||
{
|
||||
perror("Cannot open image file");
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* aggregating files: first, second, kernel, ramdisk */
|
||||
|
||||
if (first_level == NULL)
|
||||
{
|
||||
fprintf(stderr, "first level file not defined\n");
|
||||
close(fd);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (second_level == NULL)
|
||||
{
|
||||
fprintf(stderr, "second level file not defined\n");
|
||||
close(fd);
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (kernel_image == NULL)
|
||||
{
|
||||
fprintf(stderr, "kernel image file not defined\n");
|
||||
close(fd);
|
||||
return 5;
|
||||
}
|
||||
|
||||
ret = aggregate(fd, first_level, second_level, kernel_image, ramdisk);
|
||||
if (ret != 0)
|
||||
{
|
||||
perror("Cannot create image\n");
|
||||
close(fd);
|
||||
return 6;
|
||||
}
|
||||
|
||||
/* set first level info */
|
||||
|
||||
ret = first_tune(fd, second_level);
|
||||
if (ret != 0)
|
||||
{
|
||||
close(fd);
|
||||
return 7;
|
||||
}
|
||||
|
||||
/* set second level info */
|
||||
|
||||
ret = second_tune(fd, second_level, kernel_image, buffer_size, ramdisk);
|
||||
if (ret != 0)
|
||||
{
|
||||
close(fd);
|
||||
return 8;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char* first_level = NULL;
|
||||
char* second_level = NULL;
|
||||
char* kernel_image = NULL;
|
||||
char* ramdisk = NULL;
|
||||
unsigned long buffer_size = 0;
|
||||
char* image = NULL;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if ((argc != 12) && (argc != 10))
|
||||
{
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (strcmp("-f", argv[i]) == 0)
|
||||
{
|
||||
if (first_level != NULL)
|
||||
{
|
||||
fprintf(stderr, "Duplicate definition of -f\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if (i < argc)
|
||||
first_level = argv[i];
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Missing argument for -f\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp("-s", argv[i]) == 0)
|
||||
{
|
||||
if (second_level != NULL)
|
||||
{
|
||||
fprintf(stderr, "Duplicate definition of -s\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if (i < argc)
|
||||
second_level = argv[i];
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Missing argument for -s\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp("-i", argv[i]) == 0)
|
||||
{
|
||||
if (kernel_image != NULL)
|
||||
{
|
||||
fprintf(stderr, "Duplicate definition of -i\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if (i < argc)
|
||||
kernel_image = argv[i];
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Missing argument for -i\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp("-b", argv[i]) == 0)
|
||||
{
|
||||
if (buffer_size != 0)
|
||||
{
|
||||
fprintf(stderr, "Duplicate definition of -b\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if (i < argc)
|
||||
buffer_size = atol(argv[i]);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Missing argument for -b\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp("-r", argv[i]) == 0)
|
||||
{
|
||||
if (ramdisk != 0)
|
||||
{
|
||||
fprintf(stderr, "Duplicate definition of -r\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if (i < argc)
|
||||
ramdisk = argv[i];
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Missing argument for -r\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image != NULL)
|
||||
{
|
||||
fprintf(stderr, "Unknown parameter %s\n",
|
||||
argv[i]);
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
image = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
ret = create_image(first_level, second_level, kernel_image, ramdisk,
|
||||
buffer_size, image);
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue
Block a user