Exemple #1
0
static long DecodeSegment(long cmdBase)
{
  struct segment_command *segCmd;
  char   rangeName[32];
  char   *vmaddr, *fileaddr;
  long   vmsize, filesize;
  
  segCmd = (struct segment_command *)cmdBase;
  
  vmaddr = (char *)segCmd->vmaddr;
  vmsize = segCmd->vmsize;
  
  fileaddr = (char *)(gPPCAddress + segCmd->fileoff);
  filesize = segCmd->filesize;
  
#if 0
  printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n",
	 segCmd->segname, vmaddr, vmsize, fileaddr, filesize,
	 segCmd->nsects, segCmd->flags);
#endif
  
  // Add the Segment to the memory-map.
  sprintf(rangeName, "Kernel-%s", segCmd->segname);
  AllocateMemoryRange(rangeName, (long)vmaddr, vmsize);

  if (vmsize && (strcmp(segCmd->segname, "__PRELINK") == 0))
    gHaveKernelCache = 1;
  
  // Handle special segments first.
  
  // If it is the vectors, save them in their special place.
  if ((strcmp(segCmd->segname, "__VECTORS") == 0) &&
      ((long)vmaddr < (kVectorAddr + kVectorSize)) &&
      (vmsize != 0) && (filesize != 0)) {
    
    // Copy the first part into the save area.
    bcopy(fileaddr, gVectorSaveAddr,
	  (filesize <= kVectorSize) ? filesize : kVectorSize);
    
    // Copy the rest into memory.
    if (filesize > kVectorSize)
      bcopy(fileaddr + kVectorSize, (char *)kVectorSize,
	    filesize - kVectorSize);
    
    return 0;
  }
  
  // It is nothing special, so do the usual. Only copy sections
  // that have a filesize.  Others are handle by the original bzero.
  if (filesize != 0) {
    bcopy(fileaddr, vmaddr, filesize);
  }
  
  // Adjust the last address used by the kernel
  if ((long)vmaddr + vmsize > AllocateKernelMemory(0)) {
    AllocateKernelMemory((long)vmaddr + vmsize - AllocateKernelMemory(0));
  }
  
  return 0;
}
Exemple #2
0
static long DecodeSymbolTable(long cmdBase)
{
  struct symtab_command *symTab, *symTableSave;
  long   tmpAddr, symsSize, totalSize;
  
  symTab = (struct symtab_command *)cmdBase;
  
#if 0
  printf("symoff: %x, nsyms: %x, stroff: %x, strsize: %x\n",
	 symTab->symoff, symTab->nsyms, symTab->stroff, symTab->strsize);
#endif
  
  symsSize = symTab->stroff - symTab->symoff;
  totalSize = symsSize + symTab->strsize;
  
  gSymbolTableSize = totalSize + sizeof(struct symtab_command);
  gSymbolTableAddr = AllocateKernelMemory(gSymbolTableSize);
  
  // Add the SymTab to the memory-map.
  AllocateMemoryRange("Kernel-__SYMTAB", gSymbolTableAddr, gSymbolTableSize);
  
  symTableSave = (struct symtab_command *)gSymbolTableAddr;
  tmpAddr = gSymbolTableAddr + sizeof(struct symtab_command);
  
  symTableSave->symoff = tmpAddr;
  symTableSave->nsyms = symTab->nsyms;
  symTableSave->stroff = tmpAddr + symsSize;
  symTableSave->strsize = symTab->strsize;
  
  bcopy((char *)(gPPCAddress + symTab->symoff),
	(char *)tmpAddr, totalSize);
  
  return 0;
}
// Assumes mkext driver has been loaded to kLoadAddr already
long 
AddDriverMKext( void )
{
	long driversAddr, driversLength;
	char segName[32];

	DriversPackage *package = (DriversPackage *)kLoadAddr;

	// Verify the MKext.
	if( (package->signature1 != kDriverPackageSignature1) ||
	    (package->signature2 != kDriverPackageSignature2)) return -1;
	if( package->length > kLoadSize) return -1;
	if( package->alder32 != Alder32((unsigned char *)&package->version,
					package->length - 0x10)) return -1;

	// Make space for the MKext.
	driversLength = package->length;
	driversAddr = AllocateKernelMemory(driversLength);

	// Copy the MKext.
	memcpy((void *)driversAddr, (void *)kLoadAddr, driversLength);
	
	// Add the MKext to the memory map.
	sprintf(segName, "DriversPackage-%lx", driversAddr);
	//printm("DriversPackage-%lx\n", driversAddr);
	AllocateMemoryRange(segName, driversAddr, driversLength);
	
	return 0;
}
Exemple #4
0
/**
 * enter additional data into the DeviceTree
 */
int prepare_devicetree_stage2(void)
{
    void *deviceTreeP;
    uint32_t deviceTreeLength;
    Node *memory_map = CreateMemoryMapNode();
    assert(memory_map);

    /* Insert the cool iBoot-like stuff. */
    uint32_t one = 1;
    uint64_t ecid = 0xBEEFBEEFBEEFBEEF;

    assert(gChosen);
    CreateDeviceTreeNode(gChosen, "firmware-version", "iBoot-1234.5.6~93", sizeof("iBoot-1234.5.6~93"));
    CreateDeviceTreeNode(gChosen, "debug-enabled", &one, sizeof(uint32_t));
    CreateDeviceTreeNode(gChosen, "secure-boot", &one, sizeof(uint32_t));    

    CreateDeviceTreeNode(gChosen, "die-id", &ecid, sizeof(uint64_t));    
    CreateDeviceTreeNode(gChosen, "unique-chip-id", &ecid, sizeof(uint64_t));    

    CreateDeviceTreeNode(DT__RootNode(), "serial-number", "SOMESRNLNMBR", sizeof("SOMESRNLNMBR"));

    /* Verify we have a ramdisk. */
    if (ramdisk_base) {
        void *reloc_ramdisk_base =
            (void *)memory_region_reserve(&kernel_region, ramdisk_size,
                                          4096);
        printf
            ("creating ramdisk at 0x%x of size 0x%x, from image at 0x%x\n",
             reloc_ramdisk_base, ramdisk_size, ramdisk_base);
        bcopy((void *)ramdisk_base, reloc_ramdisk_base, ramdisk_size);
        AllocateMemoryRange(memory_map, "RAMDisk",
                            (uint32_t) reloc_ramdisk_base, ramdisk_size,
                            kBootDriverTypeInvalid);
    }

    /* Flatten the finalized device-tree image. */
    DT__FlattenDeviceTree(NULL, &deviceTreeLength);

    /* Allocate memory for it. */
    deviceTreeP = memory_region_reserve(&kernel_region, deviceTreeLength, 0);

    /* Flatten. */
    DT__FlattenDeviceTree((void **)&deviceTreeP, &deviceTreeLength);

    /* Enter into Boot-Args */
    gBootArgs.deviceTreeLength = deviceTreeLength;
    gBootArgs.deviceTreeP =
        (void *)phystov(deviceTreeP, gBootArgs.virtBase, gBootArgs.physBase);
    printf("creating device tree at 0x%x of size 0x%x\n", deviceTreeP,
           deviceTreeLength);

    return true;
}
Exemple #5
0
void NBI_md0Ramdisk()
{
	RAMDiskParam ramdiskPtr;
	char filename[512];
	int fh = -1;
	
	// TODO: embed NBI.img in this file
	// If runNetbookInstaller is true, then the system has changed states, patch it 
	snprintf(filename, sizeof(filename),"%s", "Extra/NetbookInstaller.img");;
	fh = open(filename, 0);
	
	if (fh >= 0)
	{
		verbose("Enabling ramdisk %s\n", filename);
		
		ramdiskPtr.size  = file_size(fh);
		ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);
		
		if(ramdiskPtr.size && ramdiskPtr.base)
		{
			// Read new ramdisk image contents in kernel memory.
			if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size)
			{				
				
                AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size);
				
				Node* node = DT__FindNode("/chosen/memory-map", false);
				if(node != NULL)
				{
					DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam),  (void*)&ramdiskPtr);		
				}
				else
				{
					verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);
				}
			}
			else
			{
				verbose("Unable to read md0 image %s.\n", filename);
			}			
		}
		else
		{
			verbose("md0 image %s is empty.\n", filename);
		}
		
		close(fh);
		
	}
}
Exemple #6
0
long
LoadDriverMKext( char * fileSpec )
{
	unsigned long    driversAddr, driversLength;
	long             length;
	char             segName[32];
	DriversPackage * package;

#define GetPackageElement(e)     OSSwapBigToHostInt32(package->e)

	// Load the MKext.
	length = LoadThinFatFile(fileSpec, (void **)&package);
	if (length < sizeof (DriversPackage)) {
		return -1;
	}

	// call hook to notify modules that the mkext has been loaded
	execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) &length, NULL);

	
	// Verify the MKext.
	if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
		( GetPackageElement(signature2) != kDriverPackageSignature2) ||
		( GetPackageElement(length)      > kLoadSize )               ||
		( GetPackageElement(adler32)    !=
		Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
	{
		return -1;
	}

	// Make space for the MKext.
	driversLength = GetPackageElement(length);
	driversAddr   = AllocateKernelMemory(driversLength);

	// Copy the MKext.
	memcpy((void *)driversAddr, (void *)package, driversLength);

	// Add the MKext to the memory map.
	snprintf(segName, sizeof(segName), "DriversPackage-%lx", driversAddr);
	AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);

	return 0;
}
Exemple #7
0
static long
LoadDriverMKext( char * fileSpec )
{
    unsigned long    driversAddr, driversLength;
    long             length;
    char             segName[32];
    DriversPackage * package = (DriversPackage *)kLoadAddr;

#define GetPackageElement(e)     OSSwapBigToHostInt32(package->e)

    // Load the MKext.
    length = LoadFile(fileSpec);
    if (length == -1) return -1;

    ThinFatFile((void **)&package, &length);

    // Verify the MKext.
    if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
        ( GetPackageElement(signature2) != kDriverPackageSignature2) ||
        ( GetPackageElement(length)      > kLoadSize )               ||
        ( GetPackageElement(alder32)    !=
          Alder32((char *)&package->version, GetPackageElement(length) - 0x10) ) )
    {
        return -1;
    }

    // Make space for the MKext.
    driversLength = GetPackageElement(length);
    driversAddr   = AllocateKernelMemory(driversLength);

    // Copy the MKext.
    memcpy((void *)driversAddr, (void *)package, driversLength);

    // Add the MKext to the memory map.
    sprintf(segName, "DriversPackage-%lx", driversAddr);
    AllocateMemoryRange(segName, driversAddr, driversLength,
                        kBootDriverTypeMKEXT);

    return 0;
}
// Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0
void md0Ramdisk()
{
	RAMDiskParam ramdiskPtr;
	char filename[512];
	const char* override_filename = 0;
	int fh = -1;
	int len;
	
	if(getValueForKey(kMD0Image, &override_filename, &len,  
				   &bootInfo->bootConfig))
	{
		// Use user specified md0 file
		sprintf(filename, "%s", override_filename);
		fh = open(filename, 0);
		
		if(fh < 0)
		{
			sprintf(filename, "rd(0,0)/Extra/%s", override_filename);
			fh = open(filename, 0);

			if(fh < 0)
			{
				sprintf(filename, "/Extra/%s", override_filename);
				fh = open(filename, 0);
			}
		}		
	}

	if(fh < 0)
	{
		sprintf(filename, "rd(0,0)/Extra/Postboot.img");
		fh = open(filename, 0);

		if(fh < 0)
		{
			sprintf(filename, "/Extra/Postboot.img");	// Check /Extra if not in rd(0,0)
			fh = open(filename, 0);
		}
	}		

	if (fh >= 0)
	{
		verbose("Enabling ramdisk %s\n", filename);

		ramdiskPtr.size  = file_size(fh);
		ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);

		if(ramdiskPtr.size && ramdiskPtr.base)
		{
			// Read new ramdisk image contents in kernel memory.
			if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size)
			{
				AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size, kBootDriverTypeInvalid);
				Node* node = DT__FindNode("/chosen/memory-map", false);
				if(node != NULL)
				{
					DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam),  (void*)&ramdiskPtr);		
				}
				else
				{
					verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);
				}
			}
			else
			{
				verbose("Unable to read md0 image %s.\n", filename);
			}			
		}
		else
		{
			verbose("md0 image %s is empty.\n", filename);
		}

		close(fh);

	}
}
Exemple #9
0
long DecodeMachO(void *binary)
{
  struct mach_header *mH;
  long   ncmds, cmdBase, cmd, cmdsize, headerBase, headerAddr, headerSize;
  long   cnt, ret = 0;
  
  gPPCAddress = (unsigned long)binary;
  
  headerBase = gPPCAddress;
  cmdBase = headerBase + sizeof(struct mach_header);
  
  mH = (struct mach_header *)(headerBase);
  if (mH->magic != MH_MAGIC) return -1;
  
#if 0
  printf("magic:      %x\n", mH->magic);
  printf("cputype:    %x\n", mH->cputype);
  printf("cpusubtype: %x\n", mH->cpusubtype);
  printf("filetype:   %x\n", mH->filetype);
  printf("ncmds:      %x\n", mH->ncmds);
  printf("sizeofcmds: %x\n", mH->sizeofcmds);
  printf("flags:      %x\n", mH->flags);
#endif
  
  ncmds = mH->ncmds;
  
  for (cnt = 0; cnt < ncmds; cnt++) {
    cmd = ((long *)cmdBase)[0];
    cmdsize = ((long *)cmdBase)[1];
    
    switch (cmd) {
      
    case LC_SEGMENT:
      ret = DecodeSegment(cmdBase);
      break;
      
    case LC_UNIXTHREAD:
      ret = DecodeUnixThread(cmdBase);
      break;
      
    case LC_SYMTAB:
      ret = DecodeSymbolTable(cmdBase);
      break;
      
    default:
      printf("Ignoring cmd type %d.\n", cmd);
      break;
    }
    
    if (ret != 0) return -1;
    
    cmdBase += cmdsize;
  }
  
  // Save the mach-o header.
  headerSize = cmdBase - headerBase;
  headerAddr = AllocateKernelMemory(headerSize);
  bcopy((char *)headerBase, (char *)headerAddr, headerSize);
  
  // Add the Mach-o header to the memory-map.
  AllocateMemoryRange("Kernel-__HEADER", headerAddr, headerSize);
  
  return ret;
}
Exemple #10
0
static long
LoadMatchedModules( void )
{
    TagPtr        prop;
    ModulePtr     module;
    char          *fileName, segName[32];
    DriverInfoPtr driver;
    long          length, driverAddr, driverLength;
    void          *driverModuleAddr = 0;

  
    module = gModuleHead;

    while (module != 0)
    {
        if (module->willLoad)
        {
            prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);

            if (prop != 0)
            {
                fileName = prop->string;
                sprintf(gFileSpec, "%s%s", module->driverPath, fileName);
                length = LoadThinFatFile(gFileSpec, &driverModuleAddr);
                //length = LoadFile(gFileSpec);
                //driverModuleAddr = (void *)kLoadAddr;
                //printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getc();
            }
            else
                length = 0;

            if (length != -1)
            {
		//driverModuleAddr = (void *)kLoadAddr;
                //if (length != 0)
                //{
		//    ThinFatFile(&driverModuleAddr, &length);
		//}

                // Make make in the image area.
                driverLength = sizeof(DriverInfo) + module->plistLength + length;
                driverAddr = AllocateKernelMemory(driverLength);

                // Set up the DriverInfo.
                driver = (DriverInfoPtr)driverAddr;
                driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
                driver->plistLength = module->plistLength;
                if (length != 0)
                {
                    driver->moduleAddr = (void *)(driverAddr + sizeof(DriverInfo) +
					                     module->plistLength);
                    driver->moduleLength = length;
                }
                else
                {
                    driver->moduleAddr   = 0;
                    driver->moduleLength = 0;
                }

                // Save the plist and module.
                strcpy(driver->plistAddr, module->plistAddr);
                if (length != 0)
                {
                    memcpy(driver->moduleAddr, driverModuleAddr, length);
                }

                // Add an entry to the memory map.
                sprintf(segName, "Driver-%lx", (unsigned long)driver);
                AllocateMemoryRange(segName, driverAddr, driverLength,
                                    kBootDriverTypeKEXT);
            }
        }
        module = module->nextModule;
    }

    return 0;
}
Exemple #11
0
static int loadMultiKext(char * path)
{
	char fileName[] = "Extensions.mkext";
	long flags, time;

	strcat(path, "/");
	
	_DRIVERS_DEBUG_DUMP("\nloadMultiKext: %s%s\n", path, fileName);

	long ret = GetFileInfo(path, fileName, &flags, &time);
	
	// Pre-flight checks; Does the file exists, and is it something we can use?
	if ((ret == STATE_SUCCESS) && ((flags & kFileTypeMask) == kFileTypeFlat))
	{
		unsigned long    driversAddr, driversLength;
		char             segName[32];
		DriversPackage * package;

		char mkextSpec[80];
		sprintf(mkextSpec, "%s%s", path, fileName);

		// Load the MKext.
		long length = LoadThinFatFile(mkextSpec, (void **)&package);

		if (length < sizeof(DriversPackage))
		{
			_DRIVERS_DEBUG_DUMP("loadMultiKext(Load Failure : -2)\n");

			return -2;
		}

		// Handy little macro (_GET_PackageElement).
		#define _GET_PE(e)	OSSwapBigToHostInt32(package->e)

		#if DEBUG_DRIVERS
			printf("\nsignature1: 0x%x\n",	_GET_PE(signature1));
			printf("signature2: 0x%x\n",	_GET_PE(signature2));
			printf("length    : %ld\n",		_GET_PE(length));
			printf("adler32   : 0x%x\n",	_GET_PE(adler32));
			printf("numDrivers: %ld\n",		_GET_PE(numDrivers));
		#endif

		// Check the MKext header.
		if ((_GET_PE(signature1) != kDriverPackageSignature1)	||
			(_GET_PE(signature2) != kDriverPackageSignature2)	||
			(_GET_PE(length)      > kLoadSize)					||
			(_GET_PE(adler32)    !=
			 localAdler32((unsigned char *)&package->version, _GET_PE(length) - 0x10)))
		{
			_DRIVERS_DEBUG_DUMP("loadMultiKext(Verification Error : -3)\n");
	
			return -3;
		}

		// Make space for the MKext.
		driversLength = _GET_PE(length);
		driversAddr   = AllocateKernelMemory(driversLength);

		// Copy the MKext.
		memcpy((void *)driversAddr, (void *)package, driversLength);
		bzero((void *)package, driversLength);

		// Add the MKext to the memory map.
		sprintf(segName, "DriversPackage-%lx", driversAddr);
		AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);

		_DRIVERS_DEBUG_DUMP("loadMultiKext(Success : 0) @ 0x%08x\n", driversAddr);

		return STATE_SUCCESS;
	}

	_DRIVERS_DEBUG_DUMP("loadMultiKext(File Not Found Error: -1)\n");

	return -1;
}