Exemplo n.º 1
0
int open_bvdev(const char *bvd, const char *path, int flags)
{
        const struct devsw	*dp;
	const char		*cp;
	BVRef			bvr;
	int			i;
	int			len;
	int			unit;
	int			partition;

	if ((i = open(path, flags)) >= 0) {
		return i;
	}

	if (bvd == NULL || (len = strlen(bvd)) < 2) {
		return -1;
	}

	for (dp=devsw; dp->name; dp++) {
		if (bvd[0] == dp->name[0] && bvd[1] == dp->name[1]) {
			unit = 0;
			partition = 0;
			/* get optional unit and partition */
			if (len >= 5 && bvd[2] == '(') { /* min must be present xx(0) */
				cp = &bvd[3];
				i = 0;
				while ((cp - path) < len && isdigit(*cp)) {
					i = i * 10 + *cp++ - '0';
					unit = i;
				}
				if (*cp++ == ',') {
					i = 0;
					while ((cp - path) < len && isdigit(*cp)) {
						i = i * 10 + *cp++ - '0';
						partition = i;
					}
				}
			}
			// turbo - bt(0,0) hook
			if ((dp->biosdev + unit) == 0x101) {
				// zef - use the ramdisk if available and the alias is active.
				if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) {
					bvr = gRAMDiskVolume;
				} else {
					bvr = gBIOSBootVolume;
				}
			} else {
				bvr = newBootVolumeRef(dp->biosdev + unit, partition);
			}
			return open_bvr(bvr, path, flags);
		}
        }
	return -1;
}
Exemplo n.º 2
0
int open_bvdev(const char *bvd, const char *path, int flags)
{
    const struct devsw	*dp;
	const char			*cp;
	BVRef				bvr;
	int					i;
	int					len;
	int					unit;
	int					partition;

	if ((i = open(path, flags)) >= 0)
	{
		return i;
	}

	if (bvd == NULL || (len = strlen(bvd)) < 2)
	{
		return -1;
	}

	for (dp=devsw; dp->name; dp++)
	{
		if (bvd[0] == dp->name[0] && bvd[1] == dp->name[1])
		{
			unit = 0;
			partition = 0;
			/* get optional unit and partition */
			if (len >= 5 && bvd[2] == '(') { /* min must be present xx(0) */
				cp = &bvd[3];
				i = 0;
				while ((cp - path) < len && isdigit(*cp))
				{
					i = i * 10 + *cp++ - '0';
					unit = i;
				}
				if (*cp++ == ',')
				{
					i = 0;
					while ((cp - path) < len && isdigit(*cp))
					{
						i = i * 10 + *cp++ - '0';
						partition = i;
					}
				}
			}
			bvr = newBootVolumeRef(dp->biosdev + unit, partition);
			return open_bvr(bvr, path, flags);
		}
    }
	return -1;
}
Exemplo n.º 3
0
/*!
    Extracts the volume selector from the pathname, returns the selected
    BVRef, and sets *outPath to the remainder of the path.
    If the path did not include a volume selector then the current volume
    is used.  When called with a volume selector the current volume
    is changed to the selected volume unless the volume selector is
    that of a ramdisk.
 */
BVRef getBootVolumeRef( const char * path, const char ** outPath )
{
    const char * cp;
    BVRef bvr = gRootVolume;
    int          biosdev = gBIOSDev;

    // Search for left parenthesis in the path specification.

    for (cp = path; *cp; cp++) {
        if (*cp == LP || *cp == '/') break;
    }

    if (*cp != LP)  // no left paren found
    {
        // Path is using the implicit current device so if there is
        // no current device, then we must fail.
        cp = path;
        if ( gRootVolume == NULL )
            return NULL;
    }
    else if ((cp - path) == 2)  // found "xx("
    {
        const struct devsw * dp;
        const char * xp = path;
        int          i;
        int unit = -1;
        int part = -1;

        cp++;

        // Check the 2 character device name pointed by 'xp'.

        for (dp = devsw; dp->name; dp++)
        {
            if ((xp[0] == dp->name[0]) && (xp[1] == dp->name[1]))
                break;  // found matching entry
        }
        if (dp->name == NULL)
        {
            error("Unknown device '%c%c'\n", xp[0], xp[1]);
            return NULL;
        }
        
        // Extract the optional unit number from the specification.
        // hd(unit) or hd(unit, part).

        i = 0;
        while (*cp >= '0' && *cp <= '9')
        {
            i = i * 10 + *cp++ - '0';
            unit = i;
        }

        // Unit is no longer optional and never really was.
        // If the user failed to specify it then the unit number from the previous kernDev
        // would have been used which makes little sense anyway.
        // For example, if the user did fd()/foobar and the current root device was the
        // second hard disk (i.e. unit 1) then fd() would select the second floppy drive!
        if(unit == -1)
            return NULL;

        // Extract the optional partition number from the specification.

        if (*cp == ',')
            part = atoi(++cp);

        // If part is not specified part will be -1 whereas before it would have been
        // whatever the last partition was which makes about zero sense if the device
        // has been switched.

        // Skip past the right paren.

        for ( ; *cp && *cp != RP; cp++) /* LOOP */;
        if (*cp == RP) cp++;
        
        biosdev = dp->biosdev + unit;

        // turbo - bt(0,0) hook
        if (biosdev == 0x101)
        {
          // zef - use the ramdisk if available and the alias is active.
          if (gRAMDiskVolume != NULL && gRAMDiskBTAliased)
            bvr = gRAMDiskVolume;
          else
            bvr = gBIOSBootVolume;
        }
        else
        {
          bvr = newBootVolumeRef(biosdev, part);
        }

        if(bvr == NULL)
            return NULL;
    }
    else
    {
        // Bad device specifier, skip past the right paren.

        for ( cp++; *cp && *cp != RP; cp++) /* LOOP */;
        if (*cp == RP) cp++;
        // If gRootVolume was NULL, then bvr will be NULL as well which
        // should be caught by the caller.
    }

    // Returns the file path following the device spec.
    // e.g. 'hd(1,b)mach_kernel' is reduced to 'mach_kernel'.

    *outPath = cp;

    return bvr;
}