/* KernPatch.c, Copyright 1997-1998 (c) by Lukas Ruf, Swiss Federal Institute of Technology, Computer Engineering and Networks Laboratory. TOPSY -- A Teachable Operating System. Implementation of a tiny and simple micro kernel for teaching purposes. For further information, please visit http://www.tik.ee.ethz.ch/~topsy This software is provided under the terms of the GNU General Public Licence. A full copy of the GNU GPL is provided in the file COPYING found in the development root of Topsy. */ /* This copyright notice supercedes all originally or previously used copyrights being used within the source code. Author: Lukas Ruf <lr@lpr.ch> */ // ************************************************************************** // // Copyrights (c) 1997 Lukas Ruf // // ************************************************************************** // // KernPatch: Read file created by size and specified as parameter 2 // // Write sizes into bytes 0x02-0x0A (8Bytes) of kernel file // // specified as parameter 1. // // Text Segment is written as ".text" // // Data Segment is written as ".rodata" (GCC stores all data in it)// // ************************************************************************** // #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MARKER "TOPSYi386" #define SIZEOFMARK 0x10 void Hello() { printf("\nKernPatch: (c) by Lukas Ruf, lr@lpr.ch\n"); printf("Program call: KernPatch <KernelFile> <KernelSizeFile>\n"); return; } unsigned long GetSize(const char *pBuf, const char *pattern) { unsigned long xret; int i = 0; char *xpos; char *xt = new char[8]; memset(xt ,0,8); xpos = strstr(pBuf,pattern); while (xpos && *xpos && (*xpos != ' ')) xpos++; // skip .text while (xpos && *xpos && (*xpos == ' ')) xpos++; // skip spaces before no. while (xpos && *xpos && (*xpos != ' ')) xt[i++] = *xpos++; // get no. xret = (unsigned long) atol(xt); delete xt; return xret; } int Patch(char *pKern, char *pSize) { int xret = 1; int fKern = open(pKern,O_RDWR); int fSize = open(pSize,O_RDONLY); char *bKern = new char[512]; char *bSize = new char[512]; char *xpos = 0; int rSize, xdo = 1; unsigned long *kernSize = new unsigned long; unsigned long *textSize = new unsigned long, *dataSize = new unsigned long; memset(bSize,0,512); memset(bKern,0,512); if (!((fKern != -1) && (read(fKern,bKern,512) == 512) && (strncmp(bKern,MARKER,strlen(MARKER)) == 0))) { printf(" !!!! NO VALID >TOPSYi386< KERNEL !!!!\n"); xdo = 0; } if (xdo) { printf("@Patching %s with %s\n",pKern,pSize); if ((fKern != -1) && (fSize != -1)) { rSize = read(fSize,bSize,512); bSize[511] = 0x00; *kernSize = lseek(fKern,0,SEEK_END); *textSize = GetSize(bSize,".text"); *dataSize = GetSize(bSize,".rodata"); *kernSize = (*kernSize / (18*512) + 1); // Calc No. of Tracks to read memcpy((void *)(bKern+SIZEOFMARK+0x00),(void *)kernSize,4); memcpy((void *)(bKern+SIZEOFMARK+0x04),(void *)textSize,4); memcpy((void *)(bKern+SIZEOFMARK+0x08),(void *)dataSize,4); printf(" tracks %.5ludec (%.8lXhex) \n",*kernSize,*kernSize); printf(" .text size %.5ludec (%.8lXhex) \n",*textSize,*textSize); printf(" .data size %.5ludec (%.8lXhex) \n",*dataSize,*dataSize); if (lseek(fKern,0,SEEK_SET) == 0) if (write(fKern,bKern,512) == 512) { printf(" => successfully completed\n"); xret = 0; } else printf(" #> impossible to write 512 Bytes to %s\n",pKern); else printf(" #> could not position file pointer to START OF FILE\n"); } else printf(" #> either %s or %s could not be opened\n",pKern,pSize); } delete textSize; delete kernSize; delete dataSize; delete bSize; delete bKern; if (fSize != -1) close(fSize); if (fKern != -1) close(fKern); return xret; } int main(int argc, char **argv) { int xret = 1; Hello(); if (argc > 2) // !! KernPatch KernFile KernSize !! if (!Patch(argv[1],argv[2])) xret = 0; return xret; }