PERFORCE change 52671 for review

Andrew Reisse areisse at FreeBSD.org
Tue May 11 08:48:48 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=52671

Change 52671 by areisse at areisse_ibook on 2004/05/11 08:48:13

	Support for reading modules for early loading.
	Bundles with a LoadEarly file are passed to the kernel to be loaded
	before iokit modules.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin73/apsl/BootX/bootx.tproj/include.subproj/sl.h#4 edit
.. //depot/projects/trustedbsd/sedarwin73/apsl/BootX/bootx.tproj/sl.subproj/drivers.c#4 edit
.. //depot/projects/trustedbsd/sedarwin73/apsl/BootX/bootx.tproj/sl.subproj/main.c#7 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin73/apsl/BootX/bootx.tproj/include.subproj/sl.h#4 (text+ko) ====

@@ -223,4 +223,14 @@
 // Externs for lzss.c
 extern int decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen);
 
+/* Early module support */
+
+struct ekmod
+{
+  char         *name;
+  void         *file;
+  size_t        filesize;
+  struct ekmod *next;
+};
+
 #endif /* ! _BOOTX_SL_H_ */

==== //depot/projects/trustedbsd/sedarwin73/apsl/BootX/bootx.tproj/sl.subproj/drivers.c#4 (text+ko) ====

@@ -146,8 +146,94 @@
 static char      gTempSpec[4096];
 static char      gFileName[4096];
 
+extern struct ekmod *emods;
+
 // Public Functions
 
+int LoadEarlyModules (char *dirSpec)
+{
+  strcat(dirSpec, "Extensions");
+
+  /* Read the early modules. For now, this does not use the iokit module
+     facility to reduce changes to the other module support here.
+     Later we may use the iokit module loader for security modules also,
+     for the features such as version checking and dependencies. */
+
+  int index = 0;
+  long ret, length, flags, time, time2, bundleType;
+  char *name, *buffer, nameb[256];
+  ModulePtr module;
+  TagPtr pers, pname, pexe;
+  while (1) {
+    ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
+    if (ret == -1) break;
+    
+    if ((flags & kFileTypeMask ) != kFileTypeDirectory) continue;
+    length = strlen(name);
+
+    if (strcmp(name + length - 5, ".kext") || strlen(name) >= 255) continue;
+
+    strcpy (nameb, name);
+
+    // Look for early module marker
+    sprintf(gTempSpec, "%s\\%s", dirSpec, name);
+    ret = GetFileInfo(gTempSpec, "LoadEarly", &flags, &time);
+    if (ret)
+      continue;
+
+    // Determine the bundle type.
+    ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
+    if (ret == 0) bundleType = kCFBundleType2;
+    else bundleType = kCFBundleType3;
+    
+    // Read the property list (for the bundle name)
+    sprintf(gFileSpec, "%s\\%s\\%sInfo.plist", dirSpec, nameb,
+	    (bundleType == kCFBundleType2) ? "Contents\\" : "");
+
+    length = LoadFile(gFileSpec);
+    if (length == -1)
+      continue;
+  
+    buffer = malloc(length + 1);
+    if (buffer == 0)
+      continue;
+    strncpy(buffer, (char *)kLoadAddr, length);
+    ret = ParseXML(buffer, &module, &pers);
+    free(buffer);
+    if (ret != 0)
+      continue;
+    pname = GetProperty (module->dict, kPropCFBundleIdentifier);
+    if (pname == 0)
+      continue;
+    pexe = GetProperty(module->dict, kPropCFBundleExecutable);
+    if (pexe == 0)
+      continue;
+
+    sprintf(gFileSpec, "%s\\%s\\%s", dirSpec, nameb,
+	    (bundleType == kCFBundleType2) ? "Contents\\MacOS\\" : "");
+    strcat (gFileSpec, pexe->string);
+    length = LoadFile(gFileSpec);
+    if (length > 1) {
+      void *module = kLoadAddr;
+      ThinFatBinary(&module, &length);
+
+      struct ekmod *mi =
+	AllocateBootXMemory (sizeof (struct ekmod) + strlen (pname->string) + 2 + length);
+      mi->name = ((char*)mi) + sizeof (struct ekmod);
+      mi->file = ((char*)mi) + sizeof (struct ekmod) + 1 + strlen (pname->string);
+      mi->filesize = length;
+      strcpy (mi->name, pname->string);
+      memcpy (mi->file, module, length);
+      mi->next = emods;
+      emods = mi;
+    }
+  }
+
+  return 0;
+}
+
+  /* Process iokit modules */
+
 long LoadDrivers(char *dirSpec)
 {
   if (gBootFileType == kNetworkDeviceType) {

==== //depot/projects/trustedbsd/sedarwin73/apsl/BootX/bootx.tproj/sl.subproj/main.c#7 (text+ko) ====

@@ -103,6 +103,8 @@
 static unsigned long gOFSPRG2Save;
 static unsigned long gOFSPRG3Save;
 
+struct ekmod *emods = NULL;
+
 // Private Functions
 
 static void Start(void *unused1, void *unused2, ClientInterfacePtr ciPtr)
@@ -176,10 +178,14 @@
   if (ret != 0) FailToBoot(3);
   
   if (!gHaveKernelCache) {
-    ret = LoadDrivers(gExtensionsSpec);
+    char extpath[4096];
+    strcpy (extpath, gExtensionsSpec);
+    ret = LoadDrivers(extpath);
     if (ret != 0) FailToBoot(4);
   }
-  
+
+  LoadEarlyModules (gExtensionsSpec);
+
   DrawSplashScreen(1);
   
   ret = SetUpBootArgs();
@@ -419,7 +425,18 @@
   return ret;
 }
 
+void AddKernData (boot_args_ptr args, const char *name, size_t size, void *data)
+{
+  int *v = (int *) AllocateKernelMemory (size + sizeof (int) * 5);
+  *v = size;
+  strcpy ((char *) (v + 1), name);
+  memcpy (v + 5, data, size);
 
+  if (args->exdata == NULL)
+    args->exdata = v;
+  args->exdatalen = (char*)AllocateKernelMemory(0)-(char*)args->exdata;
+}
+
 static long SetUpBootArgs(void)
 {
   boot_args_ptr      args;
@@ -627,35 +644,41 @@
 	strcpy (datfile, gRootDir);
 	strcat (datfile, pfilename);
 	size = LoadFile (datfile);
-	if (size > 0) {
-	  int *v = (int *) AllocateKernelMemory (size + sizeof (int) * 5);
-	  *v = size;
-	  strcpy ((char *) (v + 1), propname + 5);
-	  memcpy (v + 5, kLoadAddr, size);
-
-	  if (args->exdata == NULL)
-	    args->exdata = v;
-	  //args->exdatalen += size + sizeof(int) * 5;
-	  args->exdatalen = (char*)AllocateKernelMemory(0)-(char*)args->exdata;
-	}
+	if (size > 0)
+	  AddKernData (args, propname + 5, size, kLoadAddr);
       }
     }
     else if (!strncmp (propname, "kenv_", 5)) {
       char pvar[255];
       size = GetProp(gOptionsPH, propname, pvar, 255);
 
-      if (size > 0 && strlen(propname+4) < sizeof(int) * 4) {
-	int *v = (int *) AllocateKernelMemory (size + sizeof (int) * 5);
-	*v = size;
-	strcpy ((char *) (v + 1), propname + 5);
-	memcpy (v + 5, pvar, size);
+      if (size > 0 && strlen(propname+4) < sizeof(int) * 4)
+	AddKernData (args, propname + 5, size, pvar);
+    }
+  }
+
+  /* Load early modules */
+  int *emv = (int *) AllocateKernelMemory (0);
+  int *emo = emv;
+  strcpy ((char *) (emo+1), " modules");
+  emo[5] = 0;
+  emv = emo+6;
 
-	if (args->exdata == NULL)
-	  args->exdata = v;
-	args->exdatalen = (char*)AllocateKernelMemory(0)-(char*)args->exdata;
-      }
-    }
+  while (emods != NULL) {
+    emv[0] = 1+strlen (emods->name);
+    emv[1] = emods->filesize;
+    strcpy ((char*)(emv+2), emods->name);
+    memcpy (((char*)(emv+2))+emv[0], emods->file, emods->filesize);
+    emv = (int*) (((char *) (emv+2)) + emv[0] + emv[1]);
+    emo[5]++;
+    emods = emods->next;
   }
+  emo[0] = (char*)emv-(char*)(emo+5);
+  AllocateKernelMemory (emo[0] + sizeof(int) * 5);
+
+  if (args->exdata == NULL)
+    args->exdata = emo;
+  args->exdatalen = (char*)AllocateKernelMemory(0)-(char*)args->exdata;
 
   args->topOfKernelData = AllocateKernelMemory(0);
   


More information about the p4-projects mailing list