/* Copyright (c) 1996-1997 Swiss Federal Institute of Technology, Computer Engineering and Networks Laboratory. All rights reserved. TOPSY - A Teachable Operating System. Implementation of a tiny and simple micro kernel for teaching purposes. Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without written agreement is hereby granted, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. File: $Source: /usr/drwho/vault/cvs/topsy/Topsy/Startup/unix/start.c,v $ Author(s): George Fankhauser Affiliation: ETH Zurich, TIK Version: $Revision: 1.10 $ Creation Date: Last Date of Change: $Date: 1999/10/19 14:58:47 $ by: $Author: gfa $ */ #include "MemoryLayout.h" #include "MMMapping.h" #include "Memory.h" #include "Error.h" #include "Unix.h" #include "Startup.h" #include "Threads.h" #include // system/exec... static SegMapDescriptor segmapdesc; SegMapPtr segmap; int main() { int user_size, fd_user, fd_sym, tmp; char c; char symBuf[32]; Address userMain; sigset_t mask; // load user process from binary image file (generated by objcopy) fd_user = open("./user.bin", O_RDONLY); if (fd_user == -1) { ERROR("can't open user image [user.bin]\n"); exit(-1); } // size user user_size = 0; while (read(fd_user, &c, 1) != 0) { user_size++; } // make room for user space if (brk((void*)USERBRKAT + USERMEM) != 0) { ERROR("brk failed"); } physBase = (int)mmap((char*)USERBRKAT, user_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, fd_user, 0) - USERSTART; //printf("topsy user memory @ 0x%08x\n\n", physBase+USERSTART); // for nm to get symbol of user's "main()" program... system("rm ./user.sym"); system("nm -p user | grep 'T main' > user.sym"); fd_sym = open("./user.sym", O_RDONLY); if (fd_sym == -1) { ERROR("can't open user symbol file [user.sym]\n"); exit(-1); } read(fd_sym, symBuf, sizeof(symBuf)-1); tmp = sscanf(symBuf, "%d T main", &userMain); if (tmp != 1) { ERROR("can't read from user symbol file [user.sym]\n"); exit(-1); } close(fd_sym); #warning ______________bootStackBottom_______ // these 0x1000 sized regions are dummies for the unix port... bootStackBottom = (int)(physBase + BOOTSTACKBOTTOM); segmapdesc.kernelCodeSize = 0x1000; segmapdesc.kernelCodeStart = (Address)bootStackBottom + BOOTSTACKSIZE; segmapdesc.kernelDataSize = 0x1000; segmapdesc.kernelDataStart = (Address)segmapdesc.kernelCodeStart + segmapdesc.kernelCodeSize; segmapdesc.userCodeSize = user_size; segmapdesc.userCodeStart = (Address)physBase + USERSTART; segmapdesc.userDataSize = 0x1000; segmapdesc.userDataStart = (Address)physBase + USERSTART + user_size; segmapdesc.userJumpAddress = (Address)userMain; /* from nm output" */ segmapdesc.userLoadedInKernelAt = 0; segmap = &segmapdesc; topsyMain(); // as of version 1.2 this is the new main function name } // __main() {} // depending on libraries this is needed (native) or not (unix) #ifdef __gnu_ld__ void _start(){main();}// dep. on ld this is needed (gnu ld) or not (sun ld) #endif