[OpenBIOS] Patch for auto partition selection

Programmingkid programmingkidx at gmail.com
Fri Oct 26 23:42:18 CEST 2012


This patch implements the auto partition selection feature. It makes commands like these works: "dir cd:,\" and "boot cd:,\\:tbxi". 

Any progress with the local variable patch? 

---
 packages/mac-parts.c |  180 ++++++++++++++++++++++++++++----------------------
 1 files changed, 102 insertions(+), 78 deletions(-)

diff --git a/packages/mac-parts.c b/packages/mac-parts.c
index 18e4aa3..7e32423 100644
--- a/packages/mac-parts.c
+++ b/packages/mac-parts.c
@@ -34,7 +34,7 @@ do { printk("MAC-PARTS: " fmt , ##args); } while (0)
 typedef struct {
 	xt_t		seek_xt, read_xt;
 	ucell	        offs_hi, offs_lo;
-        ucell	        size_hi, size_lo;
+   ucell	        size_hi, size_lo;
 	unsigned int	blocksize;
 	phandle_t	filesystem_ph;
 } macparts_info_t;
@@ -58,15 +58,15 @@ macparts_open( macparts_info_t *di )
 	int want_bootcode = 0;
 	phandle_t ph;
 	ducell offs = 0, size = -1;
-
+   
 	DPRINTF("macparts_open '%s'\n", str );
-
+   
 	/* 
-		Arguments that we accept:
-		id: [0-7]
-		[(id)][,][filespec]
-	*/
-
+    Arguments that we accept:
+    id: [0-7]
+    [(id)][,][filespec]
+    */
+   
 	if( str ) {
 		if ( !strlen(str) )
 			parnum = -1;
@@ -74,52 +74,52 @@ macparts_open( macparts_info_t *di )
 			/* Detect the boot parameters */
 			char *ptr;
 			ptr = str;
-
+         
 			/* <id>,<file> */
 			if (*ptr >= '0' && *ptr <= '9' && *(ptr + 1) == ',') {
 				parstr = ptr;
 				*(ptr + 1) = '\0';
 				argstr = ptr + 2;
 			}
-
+         
 			/* <id> */
 			else if (*ptr >= '0' && *ptr <='9' && *(ptr + 1) == '\0') {
 				parstr = ptr;
 			}
-
+         
 			/* ,<file> */
 			else if (*ptr == ',') {
 				argstr = ptr + 1;
 			}	
-
+         
 			/* <file> */
 			else {
 				argstr = str;
 			}
-		
+         
 			/* Convert the id to a partition number */
 			if (strlen(parstr))
 				parnum = atol(parstr);
-
+         
 			/* Detect if we are looking for the bootcode */
 			if (strcmp(argstr, "%BOOT") == 0)
 				want_bootcode = 1;
 		}
 	}
-
+   
 	DPRINTF("parstr: %s  argstr: %s  parnum: %d\n", parstr, argstr, parnum);
-
+   
 	DPRINTF("want_bootcode %d\n", want_bootcode);
 	DPRINTF("macparts_open %d\n", parnum);
-
+   
 	di->filesystem_ph = 0;
 	di->read_xt = find_parent_method("read");
 	di->seek_xt = find_parent_method("seek");
-
+   
 	SEEK( 0 );
 	if( READ(&dmap, sizeof(dmap)) != sizeof(dmap) )
 		goto out;
-
+   
 	/* partition maps might support multiple block sizes; in this case,
 	 * pmPyPartStart is typically given in terms of 512 byte blocks.
 	 */
@@ -133,121 +133,145 @@ macparts_open( macparts_info_t *di )
 	SEEK( bs );
 	if( READ(&par, sizeof(par)) != sizeof(par) )
 		goto out;
-        if (__be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE)
+   if (__be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE)
 		goto out;
-
+   
 	/*
 	 * Implement partition selection as per the PowerPC Microprocessor CHRP bindings
 	 */
-
-	if (str == NULL || parnum == 0) {
-		/* According to the spec, partition 0 as well as no arguments means the whole disk */
+   
+	if (parnum == 0) {
+		/* According to the spec, partition 0 means the whole disk */
 		offs = (long long)0;
 		size = (long long)__be32_to_cpu(dmap.sbBlkCount) * bs;
-
+      
 		di->blocksize = (unsigned int)bs;
-
+      
 		di->offs_hi = offs >> BITS;
 		di->offs_lo = offs & (ucell) -1;
-	
+      
 		di->size_hi = size >> BITS;
 		di->size_lo = size & (ucell) -1;
-
+      
 		ret = -1;
 		goto out;
-
-	} else if (parnum == -1 && strlen(argstr)) {
-
+      
+	} 
+   
+   // if not partition, but a file was specified - example: boot cd:,\\:tbxi
+   else if (parnum == -1 && strlen(argstr))  
+   {
 		DPRINTF("mac-parts: counted %d partitions\n", __be32_to_cpu(par.pmMapBlkCnt));
-
+      
 		/* No partition was explicitly requested, but an argstr was passed in.
-		   So let's find a suitable partition... */
-		for (parnum = 1; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++) {
+       So let's find a suitable partition... */
+		for (parnum = 1; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++) 
+      {
 			SEEK( bs * parnum );
 			READ( &par, sizeof(par) );
-			if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE ||
-                            !__be32_to_cpu(par.pmPartBlkCnt) )
-				break;
-
 			DPRINTF("found partition type: %s with status %x\n", par.pmPartType, __be32_to_cpu(par.pmPartStatus));
-
-			/* If we have a valid, allocated and readable partition... */
-			if( (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) &&
-			(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) &&
-			(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) ) {
+         
+			// If an Apple_HFS or Apple_HFSX partition was found
+			if(strcmp(par.pmPartType, "Apple_HFS") == 0 || strcmp(par.pmPartType, "Apple_HFSX") == 0) 
+         {
 				offs = (long long)__be32_to_cpu(par.pmPyPartStart) * bs;
 				size = (long long)__be32_to_cpu(par.pmPartBlkCnt) * bs;
-
+            
 				/* If the filename was set to %BOOT, we actually want the bootcode */
-				if (want_bootcode && (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsBootValid)) {
+				if (want_bootcode && (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsBootValid)) 
+            {
 					offs += (long long)__be32_to_cpu(par.pmLgBootStart) * bs;
 					size = (long long)__be32_to_cpu(par.pmBootSize);
-
+               
 					goto found;
-				} else {
+				} 
+            
+            else 
+            {
 					/* Otherwise we were passed a filename and path. So let's
-					   choose the first partition with a valid filesystem */
+                choose the first partition with a valid filesystem */
 					DPUSH( offs );
 					PUSH_ih( my_parent() );
 					parword("find-filesystem");
-				
+               
 					ph = POP_ph();
 					if (ph)
 						goto found;
 				}
 			}
 		}
-
-	} else {
+      
+	} 
+   
+   // if no partition and no file was selected - example: "dir cd:,\"
+   else if (parnum == -1)  
+   {
+      // search for the first partition of type Apple_HFS or Apple_HFSX
+      for(parnum = 1; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++)
+      {
+         SEEK( bs * parnum );
+         READ( &par, sizeof(par) );
+         DPRINTF("found partition type: %s with status %x\n", par.pmPartType, __be32_to_cpu(par.pmPartStatus));
+         if(strcmp(par.pmPartType, "Apple_HFS") == 0 || strcmp(par.pmPartType, "Apple_HFSX") == 0)
+         {
+            offs = (long long)__be32_to_cpu(par.pmPyPartStart) * bs;
+            size = (long long)__be32_to_cpu(par.pmPartBlkCnt) * bs;
+            goto found; 
+            break;
+         }
+      }
+   }
+   
+   else {
 		/* Another partition was explicitly requested */
 		SEEK( bs * parnum );
 		READ( &par, sizeof(par) );
-
+      
 		if( (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) &&
-			    (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) &&
-			    (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) ) {
-
+         (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) &&
+         (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) ) {
+         
 			offs = (long long)__be32_to_cpu(par.pmPyPartStart) * bs;
 			size = (long long)__be32_to_cpu(par.pmPartBlkCnt) * bs;
 		}
 	}
-
+   
 	/* If we couldn't find a partition, exit */
 	if (size == -1) {
 		DPRINTF("Unable to automatically find partition!\n");
 		goto out;
 	}
-
+   
 found:
-
+   
 	ret = -1;
 	di->blocksize = (unsigned int)bs;
-
+   
 	di->offs_hi = offs >> BITS;
 	di->offs_lo = offs & (ucell) -1;
-
+   
 	di->size_hi = size >> BITS;
 	di->size_lo = size & (ucell) -1;
-
+   
 	/* We have a valid partition - so probe for a filesystem at the current offset */
 	DPRINTF("mac-parts: about to probe for fs\n");
 	DPUSH( offs );
 	PUSH_ih( my_parent() );
 	parword("find-filesystem");
 	DPRINTF("mac-parts: done fs probe\n");
-
+   
 	ph = POP_ph();
 	if( ph ) {
 		DPRINTF("mac-parts: filesystem found with ph " FMT_ucellx " and args %s\n", ph, argstr);
 		di->filesystem_ph = ph;
-
+      
 		/* If the filename was %BOOT then it's not a real filename, so clear argstr before
-		   attempting interpose */
+       attempting interpose */
 		if (want_bootcode)
 			argstr = strdup("");
-
+      
 		/* If we have been asked to open a particular file, interpose the filesystem package with 
-		   the passed filename as an argument */
+       the passed filename as an argument */
 		if (strlen(argstr)) {
 			push_str( argstr );
 			PUSH_ph( ph );
@@ -256,9 +280,9 @@ found:
 	} else {
 		DPRINTF("mac-parts: no filesystem found; bypassing misc-files interpose\n");
 	}
-
+   
 	free( str );
-
+   
 out:
 	PUSH( ret );
 }
@@ -268,7 +292,7 @@ static void
 macparts_probe( macparts_info_t *dummy )
 {
 	desc_map_t *dmap = (desc_map_t*)cell2pointer(POP());
-
+   
 	DPRINTF("macparts_probe %x ?= %x\n", dmap->sbSig, DESC_MAP_SIGNATURE);
 	if( __be16_to_cpu(dmap->sbSig) != DESC_MAP_SIGNATURE )
 		RET(0);
@@ -280,7 +304,7 @@ static void
 macparts_get_info( macparts_info_t *di )
 {
 	DPRINTF("macparts_get_info");
-
+   
 	PUSH( -1 );		/* no type */
 	PUSH( di->offs_lo );
 	PUSH( di->offs_hi );
@@ -307,21 +331,21 @@ macparts_seek(macparts_info_t *di )
 {
 	long long pos = DPOP();
 	long long offs, size;
-
+   
 	DPRINTF("macparts_seek %llx:\n", pos);
-
+   
 	/* Seek is invalid if we reach the end of the device */
 	size = ((ducell)di->size_hi << BITS) | di->size_lo;
 	if (pos > size)
 		RET( -1 );
-
+   
 	/* Calculate the seek offset for the parent */
 	offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
 	offs += pos;
 	DPUSH(offs);
-
+   
 	DPRINTF("macparts_seek parent offset %llx:\n", offs);
-
+   
 	call_package(di->seek_xt, my_parent());
 }
 
@@ -330,7 +354,7 @@ static void
 macparts_read(macparts_info_t *di )
 {
 	DPRINTF("macparts_read\n");
-
+   
 	/* Pass the read back up to the parent */
 	call_package(di->read_xt, my_parent());
 }
@@ -348,8 +372,8 @@ static void
 macparts_dir( macparts_info_t *di )
 {
 	/* On PPC Mac, the first partition chosen according to the CHRP boot
-	specification (i.e. marked as bootable) may not necessarily contain 
-	a valid FS */
+    specification (i.e. marked as bootable) may not necessarily contain 
+    a valid FS */
 	if ( di->filesystem_ph ) {
 		PUSH( my_self() );
 		push_str("dir");
-- 
1.7.5.4

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openbios.org/pipermail/openbios/attachments/20121026/c0a5e969/attachment-0001.html>


More information about the OpenBIOS mailing list