[OpenBIOS] [PATCH] Rework mac-parts.c to use CHRP-compliant partition search, followed by Apple OF partition search.

Programmingkid programmingkidx at gmail.com
Thu Dec 6 04:32:53 CET 2012


On Dec 5, 2012, at 6:24 PM, Mark Cave-Ayland wrote:

> The confusion from the previous refactoring of mac-parts.c came from the fact
> that it must support searching for a boot partition using the algorithm
> specified in the OF CHRP bindings supplement, as well as Apple's brute-force
> partition-type search.
> 
> This patch corrects mac-parts.c so that it will first attempt to find a CHRP
> boot partition, and if it does not exist or fails to boot, fall back to the
> first partition that would be considered valid by Apple's OF.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
> ---
> openbios-devel/packages/mac-parts.c |  191 +++++++++++++++++++++--------------
> 1 file changed, 113 insertions(+), 78 deletions(-)
> 
> diff --git a/openbios-devel/packages/mac-parts.c b/openbios-devel/packages/mac-parts.c
> index a286870..9501bfd 100644
> --- a/openbios-devel/packages/mac-parts.c
> +++ b/openbios-devel/packages/mac-parts.c
> @@ -51,10 +51,11 @@ macparts_open( macparts_info_t *di )
> 	char *str = my_args_copy();
> 	char *argstr = strdup("");
> 	char *parstr = strdup("");
> -	int bs, parnum=-1;
> +	int bs, parnum=-1, apple_parnum=-1;
> +	int parlist[2], parlist_size = 0;
> 	desc_map_t dmap;
> 	part_entry_t par;
> -	int ret = 0;
> +	int ret = 0, i = 0, j = 0;
> 	int want_bootcode = 0;
> 	phandle_t ph;
> 	ducell offs = 0, size = -1;
> @@ -161,101 +162,135 @@ macparts_open( macparts_info_t *di )
> 		DPRINTF("mac-parts: counted %d partitions\n", __be32_to_cpu(par.pmMapBlkCnt));
> 
> 		/* No partition was explicitly requested so let's find a suitable partition... */
> -		for (parnum = 1; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++) {
> -			SEEK( bs * parnum );
> +		for (i = 1; i <= __be32_to_cpu(par.pmMapBlkCnt); i++) {
> +			SEEK( bs * i );
> 			READ( &par, sizeof(par) );
> -			if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE ||
> +			if ( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE ||
>                             !__be32_to_cpu(par.pmPartBlkCnt) )
> -				break;
> +				continue;
> 
> -			DPRINTF("found partition type: %s with status %x\n", par.pmPartType, __be32_to_cpu(par.pmPartStatus));
> +			DPRINTF("found partition %d type: %s with status %x\n", i, 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) ) {
> -				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)) {
> -					offs += (long long)__be32_to_cpu(par.pmLgBootStart) * bs;
> -					size = (long long)__be32_to_cpu(par.pmBootSize);
> -
> -					goto found;
> -				} else {
> -					/* Otherwise we were passed a filename and path. So let's
> -					   choose the first partition with a valid filesystem */
> -					DPUSH( offs );
> -					PUSH_ih( my_parent() );
> -					parword("find-filesystem");
> +
> +				/* Unfortunately Apple's OF implementation doesn't follow the OF PowerPC CHRP bindings
> +				 * and instead will brute-force boot the first valid partition it finds with a
> +				 * type of either "Apple_Boot", "Apple_HFS" or "DOS_FAT_". Here we store the id
> +				 * of the first partition that matches these criteria to use as a fallback later
> +				 * if required. */
> 				
> -					ph = POP_ph();
> -					if (ph)
> -						goto found;
> +				if (apple_parnum == -1 &&
> +				    (strcmp(par.pmPartType, "Apple_Boot") == 0 || 
> +				    strcmp(par.pmPartType, "Apple_HFS") == 0 ||
> +				    strcmp(par.pmPartType, "DOS_FAT_") == 0)) {
> +					apple_parnum = i;
> +					
> +					DPRINTF("Located Apple OF fallback partition %d\n", apple_parnum);
> +				}
> +				
> +				/* If the partition is also bootable and the pmProcessor field matches "PowerPC" (insensitive
> +				 * match), then according to the CHRP bindings this is our chosen partition */
> +				for (j = 0; j < strlen(par.pmProcessor); j++) {
> +				    par.pmProcessor[j] = tolower(par.pmProcessor[j]);
> +				}				
> +				
> +				if ((__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsBootValid) &&
> +				    strcmp(par.pmProcessor, "powerpc") == 0) {
> +				    parnum = i;
> +				
> +				    DPRINTF("Located CHRP-compliant boot partition %d\n", parnum);
> 				}
> 			}
> 		}
> +		
> +		/* If we found a valid CHRP partition, add it to the list */
> +		if (parnum > 0) {
> +		    parlist[parlist_size++] = parnum;
> +		}
> 
> +		/* If we found an Apple OF fallback partition, add it to the list */
> +		if (apple_parnum > 0 && apple_parnum != parnum) {
> +		    parlist[parlist_size++] = apple_parnum;
> +		}
> +		
> 	} 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) ) {
> -
> -			offs = (long long)__be32_to_cpu(par.pmPyPartStart) * bs;
> -			size = (long long)__be32_to_cpu(par.pmPartBlkCnt) * bs;
> -		}
> +		parlist[parlist_size++] = parnum;
> +		
> +		DPRINTF("Partition %d explicitly requested\n", parnum);
> 	}
> 
> -	/* If we couldn't find a partition, exit */
> -	if (size == -1) {
> -		DPRINTF("Unable to automatically find partition!\n");
> +	/* Attempt to use our CHRP partition, optionally followed by our Apple OF fallback partition */
> +	for (j = 0; j < parlist_size; j++) {
> +	
> +	    /* Make sure our partition is valid */
> +	    parnum = parlist[j];
> +	    
> +	    DPRINTF("Selected partition %d to boot\n", parnum);
> +	    
> +	    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)) ) {
> +		DPRINTF("Partition %d is not valid, allocated and readable\n", parnum);
> 		goto out;
> +	    }
> +	    
> +	    ret = -1;
> +
> +	    offs = (long long)__be32_to_cpu(par.pmPyPartStart) * bs;
> +	    size = (long long)__be32_to_cpu(par.pmPartBlkCnt) * bs;	
> +	    
> +	    if (want_bootcode) {
> +		offs += (long long)__be32_to_cpu(par.pmLgBootStart) * bs;
> +		size = (long long)__be32_to_cpu(par.pmBootSize);
> +	    }
> +	    
> +	    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 on partition %d with ph " FMT_ucellx " and args %s\n", parnum, ph, argstr);
> +		    di->filesystem_ph = ph;
> +
> +		    /* If the filename was %BOOT then it's not a real filename, so clear argstr before
> +		    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 */
> +		    if (strlen(argstr)) {
> +			    push_str( argstr );
> +			    PUSH_ph( ph );
> +			    fword("interpose");
> +		    }
> +		    
> +		    goto out;
> +	    } else {
> +		    DPRINTF("mac-parts: no filesystem found on partition %d; bypassing misc-files interpose\n", parnum);
> +	    }
> 	}
> -
> -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 */
> -		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 */
> -		if (strlen(argstr)) {
> -			push_str( argstr );
> -			PUSH_ph( ph );
> -			fword("interpose");
> -		}
> -	} else {
> -		DPRINTF("mac-parts: no filesystem found; bypassing misc-files interpose\n");
> -	}
> -
> +	    
> 	free( str );
> 
> out:
> -- 
> 1.7.10.4
> 
> 
> -- 
> OpenBIOS                 http://openbios.org/
> Mailinglist:  http://lists.openbios.org/mailman/listinfo
> Free your System - May the Forth be with you


I was able to make dir cd:,\ work on my Mac OS 10.2 cd and Mac OS 9 cd. Boot cd:,\\:tbxi did work for the Mac OS 10.2 cd. I can't say for sure for the Mac OS 9 cd. 




More information about the OpenBIOS mailing list