mirror of https://github.com/FDOS/kernel.git
Bart enhanced EXEFLAT for smaller packed binary; now calls UPX itself
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1063 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
279107ab8e
commit
b7a86735a2
|
@ -3,6 +3,8 @@
|
|||
+ Changes Bart
|
||||
* int2f.asm
|
||||
- bugfix: call_nls: DI register was not preserved
|
||||
* exeflat.c
|
||||
- new version exploiting better UPX compression for SYS files; calls UPX itself
|
||||
+ Changes Tom
|
||||
* inthndlr.c
|
||||
- improve handling of case where eg. FindFirst(I:\*.*) fails, causes Int24,
|
||||
|
|
|
@ -31,7 +31,6 @@ all: ..\bin\$(TARGET).sys ..\bin\country.sys
|
|||
|
||||
..\bin\$(TARGET).sys: $(TARGET).lnk $(OBJS) $(LIBS) ..\utils\exeflat.exe
|
||||
$(LINK) @$(TARGET).lnk;
|
||||
$(XUPX) kernel.exe
|
||||
..\utils\exeflat kernel.exe $*.sys $(LOADSEG) -S0x10 -S0x8B $(UPXOPT)
|
||||
copy $*.sys ..\bin\kernel.sys
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ int FDKrnConfigMain(int argc, char **argv);
|
|||
#define OEMKERNEL "IBMBIO.COM"
|
||||
#define OEMDOS "IBMDOS.COM"
|
||||
#define MSKERNEL "IO.SYS"
|
||||
#define MSDOS "MSDOS.SYS"
|
||||
#define MS_DOS "MSDOS.SYS"
|
||||
#define FDLOADSEG 0x60
|
||||
#define OEMLOADSEG 0x70
|
||||
|
||||
|
@ -523,7 +523,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
char *dosfn = OEMDOS;
|
||||
#ifdef WITHOEMCOMPATBS
|
||||
if (altkern == MS_OEMKERN) dosfn = MSDOS;
|
||||
if (altkern == MS_OEMKERN) dosfn = MS_DOS;
|
||||
#endif
|
||||
|
||||
if ( (!get_full_path(srcPath, rootPath, dosfn, srcFile)) ||
|
||||
|
|
474
utils/exeflat.c
474
utils/exeflat.c
|
@ -52,11 +52,13 @@ large portions copied from task.c
|
|||
|
||||
#define BUFSIZE 32768u
|
||||
|
||||
#define KERNEL_START 0x10 /* the kernel code really starts here at 60:10 */
|
||||
|
||||
typedef struct {
|
||||
UWORD off, seg;
|
||||
} farptr;
|
||||
|
||||
int compReloc(const void *p1, const void *p2)
|
||||
static int compReloc(const void *p1, const void *p2)
|
||||
{
|
||||
farptr *r1 = (farptr *) p1;
|
||||
farptr *r2 = (farptr *) p2;
|
||||
|
@ -71,7 +73,7 @@ int compReloc(const void *p1, const void *p2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
static void usage(void)
|
||||
{
|
||||
printf("usage: exeflat (src.exe) (dest.sys) (relocation-factor)\n");
|
||||
printf
|
||||
|
@ -80,9 +82,11 @@ void usage(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static exe_header header;
|
||||
|
||||
int exeflat(int UPX, const char *srcfile, const char *dstfile,
|
||||
const char *start, short *silentSegments, short silentcount)
|
||||
{
|
||||
exe_header header;
|
||||
int i, j;
|
||||
size_t bufsize;
|
||||
farptr *reloc;
|
||||
|
@ -91,8 +95,246 @@ int main(int argc, char **argv)
|
|||
UBYTE **buffers;
|
||||
UBYTE **curbuf;
|
||||
FILE *src, *dest;
|
||||
short silentSegments[20], silentcount = 0, silentdone = 0;
|
||||
short silentdone = 0;
|
||||
int compress_sys_file;
|
||||
|
||||
if ((src = fopen(srcfile, "rb")) == NULL)
|
||||
{
|
||||
printf("Source file %s could not be opened\n", srcfile);
|
||||
exit(1);
|
||||
}
|
||||
if (fread(&header, sizeof(header), 1, src) != 1)
|
||||
{
|
||||
printf("Error reading header from %s\n", srcfile);
|
||||
fclose(src);
|
||||
exit(1);
|
||||
}
|
||||
if (header.exSignature != MAGIC)
|
||||
{
|
||||
printf("Source file %s is not a valid .EXE\n", srcfile);
|
||||
fclose(src);
|
||||
exit(1);
|
||||
}
|
||||
if ((dest = fopen(dstfile, "wb+")) == NULL)
|
||||
{
|
||||
printf("Destination file %s could not be created\n", dstfile);
|
||||
exit(1);
|
||||
}
|
||||
start_seg = (UWORD)strtol(start, NULL, 0);
|
||||
if (header.exExtraBytes == 0)
|
||||
header.exExtraBytes = 0x200;
|
||||
printf("header len = %lu = 0x%lx\n", header.exHeaderSize * 16UL,
|
||||
header.exHeaderSize * 16UL);
|
||||
size =
|
||||
((DWORD) (header.exPages - 1) << 9) + header.exExtraBytes -
|
||||
header.exHeaderSize * 16UL;
|
||||
printf("image size (less header) = %lu = 0x%lx\n", size, size);
|
||||
printf("first relocation offset = %u = 0x%u\n", header.exOverlay,
|
||||
header.exOverlay);
|
||||
|
||||
/* first read file into memory chunks */
|
||||
fseek(src, header.exHeaderSize * 16UL, SEEK_SET);
|
||||
buffers = malloc((size_t)((size + BUFSIZE - 1) / BUFSIZE) * sizeof(char *));
|
||||
if (buffers == NULL)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
exit(1);
|
||||
}
|
||||
bufsize = BUFSIZE;
|
||||
for (to_xfer = size, curbuf = buffers; to_xfer > 0;
|
||||
to_xfer -= bufsize, curbuf++)
|
||||
{
|
||||
if (to_xfer < BUFSIZE)
|
||||
bufsize = (size_t)to_xfer;
|
||||
*curbuf = malloc(bufsize);
|
||||
if (*curbuf == NULL)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
exit(1);
|
||||
}
|
||||
if (fread(*curbuf, sizeof(char), bufsize, src) != bufsize)
|
||||
{
|
||||
printf("Source file read error %ld %d\n", to_xfer, bufsize);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (header.exRelocTable && header.exRelocItems)
|
||||
{
|
||||
fseek(src, header.exRelocTable, SEEK_SET);
|
||||
reloc = malloc(header.exRelocItems * sizeof(farptr));
|
||||
if (reloc == NULL)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
exit(1);
|
||||
}
|
||||
if (fread(reloc, sizeof(farptr), header.exRelocItems, src) !=
|
||||
header.exRelocItems)
|
||||
{
|
||||
printf("Source file read error\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fclose(src);
|
||||
qsort(reloc, header.exRelocItems, sizeof(reloc[0]), compReloc);
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
ULONG spot = ((ULONG) reloc[i].seg << 4) + reloc[i].off;
|
||||
UBYTE *spot0 = &buffers[(size_t)(spot / BUFSIZE)][(size_t)(spot % BUFSIZE)];
|
||||
UBYTE *spot1 = &buffers[(size_t)((spot + 1) / BUFSIZE)][(size_t)((spot + 1) % BUFSIZE)];
|
||||
UWORD segment = ((UWORD) * spot1 << 8) + *spot0;
|
||||
|
||||
for (j = 0; j < silentcount; j++)
|
||||
if (segment == silentSegments[j])
|
||||
{
|
||||
silentdone++;
|
||||
goto dontPrint;
|
||||
}
|
||||
|
||||
printf("relocation at 0x%04x:0x%04x ->%04x\n", reloc[i].seg,
|
||||
reloc[i].off, segment);
|
||||
|
||||
dontPrint:
|
||||
|
||||
segment += start_seg;
|
||||
*spot0 = segment & 0xff;
|
||||
*spot1 = segment >> 8;
|
||||
}
|
||||
|
||||
compress_sys_file = size < 0x10000L;
|
||||
if (UPX && !compress_sys_file) {
|
||||
/* write header without relocations to file */
|
||||
exe_header nheader = header;
|
||||
nheader.exRelocItems = 0;
|
||||
nheader.exHeaderSize = 2;
|
||||
size += 32;
|
||||
nheader.exPages = (UWORD)(size >> 9);
|
||||
nheader.exExtraBytes = (UWORD)size & 511;
|
||||
if (nheader.exExtraBytes)
|
||||
nheader.exPages++;
|
||||
if (fwrite(&nheader, sizeof(nheader), 1, dest) != 1) {
|
||||
printf("Destination file write error\n");
|
||||
exit(1);
|
||||
}
|
||||
fseek(dest, 32UL, SEEK_SET);
|
||||
}
|
||||
|
||||
/* write dest file from memory chunks */
|
||||
bufsize = BUFSIZE;
|
||||
for (to_xfer = size, curbuf = buffers; to_xfer > 0;
|
||||
to_xfer -= bufsize, curbuf++)
|
||||
{
|
||||
if (to_xfer < BUFSIZE)
|
||||
bufsize = (size_t)to_xfer;
|
||||
if (fwrite(*curbuf, sizeof(char), bufsize, dest) != bufsize)
|
||||
|
||||
{
|
||||
printf("Destination file write error\n");
|
||||
exit(1);
|
||||
}
|
||||
free(*curbuf);
|
||||
}
|
||||
|
||||
if (UPX && compress_sys_file) {
|
||||
/* overwrite first 8 bytes with SYS header */
|
||||
UWORD dhdr[4];
|
||||
fseek(dest, 0, SEEK_SET);
|
||||
for (i = 0; i < 3; i++)
|
||||
dhdr[i] = 0xffff;
|
||||
/* strategy will jump to us, interrupt never called */
|
||||
dhdr[3] = KERNEL_START;
|
||||
fwrite(dhdr, sizeof(dhdr), 1, dest);
|
||||
}
|
||||
fclose(dest);
|
||||
printf("\nProcessed %d relocations, %d not shown\n",
|
||||
header.exRelocItems, silentdone);
|
||||
return compress_sys_file;
|
||||
}
|
||||
|
||||
static void write_header(FILE *dest, size_t size)
|
||||
{
|
||||
/* UPX HEADER jump $+2+size */
|
||||
static char JumpBehindCode[] = {
|
||||
/* kernel config header - 32 bytes */
|
||||
0xeb, 0x1b, /* jmp short realentry */
|
||||
'C', 'O', 'N', 'F', 'I', 'G', 32 - 2 - 6 - 2 - 3, 0, /* WORD */
|
||||
0, /* DLASortByDriveNo db 0 */
|
||||
1, /* InitDiskShowDriveAssignment db 1 */
|
||||
2, /* SkipConfigSeconds db 2 */
|
||||
0, /* ForceLBA db 0 */
|
||||
1, /* GlobalEnableLBAsupport db 1 */
|
||||
0, /* BootHarddiskSeconds */
|
||||
|
||||
'n', 'u', 's', 'e', 'd', /* unused filler bytes */
|
||||
8, 7, 6, 5, 4, 3, 2, 1,
|
||||
/* real-entry: jump over the 'real' image do the trailer */
|
||||
0xe9, 0, 0 /* 100: jmp 103 */
|
||||
};
|
||||
|
||||
struct x {
|
||||
char y[sizeof(JumpBehindCode) == 0x20 ? 1 : -1];
|
||||
};
|
||||
|
||||
fseek(dest, 0, SEEK_SET);
|
||||
/* this assumes <= 0xfe00 code in kernel */
|
||||
*(short *)&JumpBehindCode[0x1e] += size;
|
||||
/* the UPX created-header is 32 bytes long */
|
||||
fwrite(JumpBehindCode, 1, 0x20, dest);
|
||||
}
|
||||
|
||||
static void write_trailer(FILE *dest, size_t size, int compress_sys_file)
|
||||
{
|
||||
/* UPX trailer */
|
||||
/* hand assembled - so this remains ANSI C ;-) */
|
||||
/* well almost: we still need packing and assume little endian ... */
|
||||
/* move kernel down to place CONFIG-block, which added above,
|
||||
at start_seg-2:0 (e.g. 0x5e:0) instead of
|
||||
start_seg:0 (e.g. 0x60:0) and store there boot drive number
|
||||
from BL; kernel.asm will then check presence of additional
|
||||
CONFIG-block at this address. */
|
||||
static char trailer[] = { /* shift down everything by sizeof JumpBehindCode */
|
||||
0xB9, 0x00, 0x00, /* 0 mov cx,offset trailer */
|
||||
0x0E, /* 3 push cs */
|
||||
0x1F, /* 4 pop ds (=60) */
|
||||
0x8C, 0xC8, /* 5 mov ax,cs */
|
||||
0x48, /* 7 dec ax */
|
||||
0x48, /* 8 dec ax */
|
||||
0x8E, 0xC0, /* 9 mov es,ax */
|
||||
0x93, /* 11 xchg ax,bx (to get al=bl) */
|
||||
0x31, 0xFF, /* 12 xor di,di */
|
||||
0xFC, /* 14 cld */
|
||||
0xAA, /* 15 stosb (store drive number)*/
|
||||
0x8B, 0xF7, /* 16 mov si,di */
|
||||
0xF3, 0xA4, /* 18 rep movsb */
|
||||
0x1E, /* 20 push ds */
|
||||
0x58, /* 21 pop ax */
|
||||
0x05, 0x00, 0x00, /* 22 add ax,... */
|
||||
0x8E, 0xD0, /* 25 mov ss,ax */
|
||||
0xBC, 0x00, 0x00, /* 27 mov sp,... */
|
||||
0x31, 0xC0, /* 30 xor ax,ax */
|
||||
0xFF, 0xE0 /* 32 jmp ax */
|
||||
};
|
||||
|
||||
*(short *)&trailer[1] = (short)size + 0x20;
|
||||
*(short *)&trailer[23] = header.exInitSS;
|
||||
*(short *)&trailer[28] = header.exInitSP;
|
||||
if (compress_sys_file)
|
||||
/* replace by jmp word ptr [6]: ff 26 06 00
|
||||
(the .SYS strategy handler which will unpack) */
|
||||
*(long *)&trailer[30] = 0x000626ffL;
|
||||
fwrite(trailer, 1, sizeof(trailer), dest);
|
||||
fclose(dest);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
short silentSegments[20], silentcount = 0;
|
||||
int compress_sys_file;
|
||||
char *upx, *tmpexe, *buffer;
|
||||
char cmdbuf[128];
|
||||
int UPX = FALSE;
|
||||
int i;
|
||||
FILE *dest;
|
||||
long size;
|
||||
|
||||
/* if no arguments provided, show usage and exit */
|
||||
if (argc < 4) usage();
|
||||
|
@ -131,196 +373,66 @@ int main(int argc, char **argv)
|
|||
/* arguments left :
|
||||
infile outfile relocation offset */
|
||||
|
||||
if ((src = fopen(argv[1], "rb")) == NULL)
|
||||
{
|
||||
printf("Source file %s could not be opened\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
if (fread(&header, sizeof(header), 1, src) != 1)
|
||||
{
|
||||
printf("Error reading header from %s\n", argv[1]);
|
||||
fclose(src);
|
||||
return 1;
|
||||
}
|
||||
if (header.exSignature != MAGIC)
|
||||
{
|
||||
printf("Source file %s is not a valid .EXE\n", argv[1]);
|
||||
fclose(src);
|
||||
return 1;
|
||||
}
|
||||
if ((dest = fopen(argv[2], "wb+")) == NULL)
|
||||
{
|
||||
printf("Destination file %s could not be created\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
start_seg = (UWORD)strtol(argv[3], NULL, 0);
|
||||
if (header.exExtraBytes == 0)
|
||||
header.exExtraBytes = 0x200;
|
||||
printf("header len = %lu = 0x%lx\n", header.exHeaderSize * 16UL,
|
||||
header.exHeaderSize * 16UL);
|
||||
size =
|
||||
((DWORD) (header.exPages - 1) << 9) + header.exExtraBytes -
|
||||
header.exHeaderSize * 16UL;
|
||||
printf("image size (less header) = %lu = 0x%lx\n", size, size);
|
||||
printf("first relocation offset = %u = 0x%u\n", header.exOverlay,
|
||||
header.exOverlay);
|
||||
compress_sys_file = exeflat(UPX, argv[1], argv[2], argv[3],
|
||||
silentSegments, silentcount);
|
||||
if (!UPX)
|
||||
exit(0);
|
||||
|
||||
/* first read file into memory chunks */
|
||||
fseek(src, header.exHeaderSize * 16UL, SEEK_SET);
|
||||
buffers = malloc((size_t)((size + BUFSIZE - 1) / BUFSIZE) * sizeof(char *));
|
||||
if (buffers == NULL)
|
||||
/* move kernel.sys tmp$$$$$.exe */
|
||||
tmpexe = argv[2];
|
||||
if (!compress_sys_file)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
return 1;
|
||||
}
|
||||
bufsize = BUFSIZE;
|
||||
for (to_xfer = size, curbuf = buffers; to_xfer > 0;
|
||||
to_xfer -= bufsize, curbuf++)
|
||||
{
|
||||
if (to_xfer < BUFSIZE)
|
||||
bufsize = (size_t)to_xfer;
|
||||
*curbuf = malloc(bufsize);
|
||||
if (*curbuf == NULL)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
return 1;
|
||||
}
|
||||
if (fread(*curbuf, sizeof(char), bufsize, src) != bufsize)
|
||||
{
|
||||
printf("Source file read error %ld %d\n", to_xfer, bufsize);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (header.exRelocTable && header.exRelocItems)
|
||||
{
|
||||
fseek(src, header.exRelocTable, SEEK_SET);
|
||||
reloc = malloc(header.exRelocItems * sizeof(farptr));
|
||||
if (reloc == NULL)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
return 1;
|
||||
}
|
||||
if (fread(reloc, sizeof(farptr), header.exRelocItems, src) !=
|
||||
header.exRelocItems)
|
||||
{
|
||||
printf("Source file read error\n");
|
||||
return 1;
|
||||
}
|
||||
fclose(src);
|
||||
qsort(reloc, header.exRelocItems, sizeof(reloc[0]), compReloc);
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
ULONG spot = ((ULONG) reloc[i].seg << 4) + reloc[i].off;
|
||||
UBYTE *spot0 = &buffers[(size_t)(spot / BUFSIZE)][(size_t)(spot % BUFSIZE)];
|
||||
UBYTE *spot1 = &buffers[(size_t)((spot + 1) / BUFSIZE)][(size_t)((spot + 1) % BUFSIZE)];
|
||||
UWORD segment = ((UWORD) * spot1 << 8) + *spot0;
|
||||
|
||||
for (j = 0; j < silentcount; j++)
|
||||
if (segment == silentSegments[j])
|
||||
{
|
||||
silentdone++;
|
||||
goto dontPrint;
|
||||
tmpexe = "tmp$$$$$.exe";
|
||||
rename(argv[2], tmpexe);
|
||||
}
|
||||
|
||||
printf("relocation at 0x%04x:0x%04x ->%04x\n", reloc[i].seg,
|
||||
reloc[i].off, segment);
|
||||
upx = getenv("XUPX");
|
||||
if (upx == NULL)
|
||||
upx = "UPX";
|
||||
|
||||
dontPrint:
|
||||
#if !defined(__TURBOC__)
|
||||
/* upx kernel.exe -o kernel.sys */
|
||||
_snprintf(cmdbuf, sizeof cmdbuf, "%s %s", upx, tmpexe);
|
||||
#else
|
||||
/* oh well, let's hope for no buffer overflow...*/
|
||||
sprintf(cmdbuf, "%s %s", upx, tmpexe);
|
||||
#endif
|
||||
|
||||
segment += start_seg;
|
||||
*spot0 = segment & 0xff;
|
||||
*spot1 = segment >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (UPX)
|
||||
if (system(cmdbuf))
|
||||
{
|
||||
/* UPX HEADER jump $+2+size */
|
||||
static char JumpBehindCode[] = {
|
||||
/* kernel config header - 32 bytes */
|
||||
0xeb, 0x1b, /* jmp short realentry */
|
||||
'C', 'O', 'N', 'F', 'I', 'G', 32 - 2 - 6 - 2 - 3, 0, /* WORD */
|
||||
0, /* DLASortByDriveNo db 0 */
|
||||
1, /* InitDiskShowDriveAssignment db 1 */
|
||||
2, /* SkipConfigSeconds db 2 */
|
||||
0, /* ForceLBA db 0 */
|
||||
1, /* GlobalEnableLBAsupport db 1 */
|
||||
0, /* BootHarddiskSeconds */
|
||||
printf("Problems executing %s\n", cmdbuf);
|
||||
remove(tmpexe);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
'n', 'u', 's', 'e', 'd', /* unused filler bytes */
|
||||
8, 7, 6, 5, 4, 3, 2, 1,
|
||||
/* real-entry: jump over the 'real' image do the trailer */
|
||||
0xe9, 0, 0 /* 100: jmp 103 */
|
||||
};
|
||||
if (!compress_sys_file)
|
||||
{
|
||||
size = exeflat(FALSE, tmpexe, argv[2], argv[3],
|
||||
silentSegments, silentcount);
|
||||
remove(tmpexe);
|
||||
}
|
||||
/* argv[2] does now contain the final flattened file: just
|
||||
header and trailer need to be added */
|
||||
/* the compressed file has two chunks max */
|
||||
|
||||
struct x {
|
||||
char y[sizeof(JumpBehindCode) == 0x20 ? 1 : -1];
|
||||
};
|
||||
if ((dest = fopen(argv[2], "rb+")) == NULL)
|
||||
{
|
||||
printf("Destination file %s could not be opened\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buffer = malloc(0xfe01);
|
||||
|
||||
fread(buffer, 0xfe01, 1, dest);
|
||||
size = ftell(dest);
|
||||
if (size >= 0xfe00u)
|
||||
{
|
||||
printf("kernel; size too large - must be <= 0xfe00\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* this assumes <= 0xfe00 code in kernel */
|
||||
*(short *)&JumpBehindCode[0x1e] += (short)size;
|
||||
fwrite(JumpBehindCode, 1, 0x20, dest);
|
||||
}
|
||||
|
||||
/* write dest file from memory chunks */
|
||||
bufsize = BUFSIZE;
|
||||
for (to_xfer = size, curbuf = buffers; to_xfer > 0;
|
||||
to_xfer -= bufsize, curbuf++)
|
||||
{
|
||||
if (to_xfer < BUFSIZE)
|
||||
bufsize = (size_t)to_xfer;
|
||||
if (fwrite(*curbuf, sizeof(char), bufsize, dest) != bufsize)
|
||||
|
||||
{
|
||||
printf("Destination file write error\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (UPX)
|
||||
{
|
||||
/* UPX trailer */
|
||||
/* hand assembled - so this remains ANSI C ;-) */
|
||||
/* move kernel down to place CONFIG-block, which added above,
|
||||
at start_seg-2:0 (e.g. 0x5e:0) instead of
|
||||
start_seg:0 (e.g. 0x60:0) and store there boot drive number
|
||||
from BL; kernel.asm will then check presence of additional
|
||||
CONFIG-block at this address. */
|
||||
static char trailer[] = {
|
||||
0x0E, /* 0 push cs */
|
||||
0x1F, /* 1 pop ds ; =0x60 */
|
||||
0x8C,0xDF, /* 2 mov di,ds */
|
||||
0x4F, /* 4 dec di */
|
||||
0x4F, /* 5 dec di */
|
||||
0x8E,0xC7, /* 6 mov es,di */
|
||||
0xFC, /* 8 cld */
|
||||
0x33,0xFF, /* 9 xor di,di */
|
||||
0x93, /* 11 xchg ax,bx ; mov al,bl */
|
||||
0xAA, /* 12 stosb ; mov [es:0],al */
|
||||
0x8B,0xF7, /* 13 mov si,di */
|
||||
0xB9,0x00,0x00, /* 15 mov cx,offset trailer */
|
||||
0xF3,0xA4, /* 18 rep movsb */
|
||||
0x1E, /* 20 push ds */
|
||||
0x58, /* 21 pop ax */
|
||||
0x05,0x00,0x00, /* 22 add ax,... */
|
||||
0x8E,0xD0, /* 25 mov ss,ax */
|
||||
0xBC,0x00,0x00, /* 27 mov sp,... */
|
||||
0x31,0xC0, /* 30 xor ax,ax */
|
||||
0xFF,0xE0, /* 32 jmp ax ; jmp 0 */
|
||||
};
|
||||
*(short *)&trailer[16] = (short)size + 0x20;
|
||||
*(short *)&trailer[23] = header.exInitSS;
|
||||
*(short *)&trailer[28] = header.exInitSP;
|
||||
fwrite(trailer, 1, sizeof trailer, dest);
|
||||
}
|
||||
fclose(dest);
|
||||
printf("\nProcessed %d relocations, %d not shown\n",
|
||||
header.exRelocItems, silentdone);
|
||||
fseek(dest, 0, SEEK_SET);
|
||||
write_header(dest, (size_t)size);
|
||||
fwrite(buffer, (size_t)size, 1, dest);
|
||||
write_trailer(dest, (size_t)size, compress_sys_file);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue