mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-22 19:21:04 +01:00
Initial storage functionality for U-Boot support library.
- Only non-sliced bsdlabel style partitioning is currently supported (but provisions are made towards GPT support, which should follow soon) - Enable storage support in loader on ARM Obtained from: Semihalf
This commit is contained in:
parent
a715909b3e
commit
11cdd0c0c2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=185099
@ -10,8 +10,8 @@ WARNS?= 1
|
||||
# Architecture-specific loader code
|
||||
SRCS= start.S conf.c vers.c
|
||||
|
||||
LOADER_DISK_SUPPORT?= no
|
||||
LOADER_UFS_SUPPORT?= no
|
||||
LOADER_DISK_SUPPORT?= yes
|
||||
LOADER_UFS_SUPPORT?= yes
|
||||
LOADER_CD9660_SUPPORT?= no
|
||||
LOADER_EXT2FS_SUPPORT?= no
|
||||
LOADER_NET_SUPPORT?= yes
|
||||
|
@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
struct devsw *devsw[] = {
|
||||
#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT)
|
||||
&uboot_disk,
|
||||
&uboot_storage,
|
||||
#endif
|
||||
#if defined(LOADER_NET_SUPPORT)
|
||||
&netdev,
|
||||
|
@ -3,4 +3,5 @@ $FreeBSD$
|
||||
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
|
||||
file is important. Make sure the current version number is on line 6.
|
||||
|
||||
1.0: Added storage support. Booting from HDD, USB, etc. is now possible.
|
||||
0.5: Initial U-Boot/arm version (netbooting only).
|
||||
|
@ -64,7 +64,7 @@ uboot_getdev(void **vdev, const char *devspec, const char **path)
|
||||
/*
|
||||
* Try to parse the device name off the beginning of the devspec.
|
||||
*/
|
||||
return(uboot_parsedev(dev, devspec, path));
|
||||
return (uboot_parsedev(dev, devspec, path));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -78,7 +78,7 @@ uboot_getdev(void **vdev, const char *devspec, const char **path)
|
||||
*
|
||||
* For disk-type devices, the syntax is:
|
||||
*
|
||||
* disk<unit>[s<slice>][<partition>]:
|
||||
* disk<unit>[<partition>]:
|
||||
*
|
||||
*/
|
||||
static int
|
||||
@ -86,10 +86,10 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
|
||||
const char **path)
|
||||
{
|
||||
struct uboot_devdesc *idev;
|
||||
struct devsw *dv;
|
||||
char *cp;
|
||||
const char *np;
|
||||
int i, unit, slice, partition, err;
|
||||
struct devsw *dv;
|
||||
char *cp;
|
||||
const char *np;
|
||||
int i, unit, partition, err;
|
||||
|
||||
/* minimum length check */
|
||||
if (strlen(devspec) < 2)
|
||||
@ -110,12 +110,11 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
|
||||
np = (devspec + strlen(dv->dv_name));
|
||||
|
||||
switch(dv->dv_type) {
|
||||
case DEVT_NONE: /* XXX what to do here? Do we care? */
|
||||
case DEVT_NONE:
|
||||
break;
|
||||
|
||||
case DEVT_DISK:
|
||||
unit = -1;
|
||||
slice = -1;
|
||||
partition = -1;
|
||||
if (*np && (*np != ':')) {
|
||||
/* next comes the unit number */
|
||||
@ -124,16 +123,8 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
|
||||
err = EUNIT;
|
||||
goto fail;
|
||||
}
|
||||
if (*cp == 's') { /* got a slice number */
|
||||
np = cp + 1;
|
||||
slice = strtol(np, &cp, 10);
|
||||
if (cp == np) {
|
||||
err = ESLICE;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (*cp && (*cp != ':')) {
|
||||
/* get a partition number */
|
||||
/* get partition */
|
||||
partition = *cp - 'a';
|
||||
if ((partition < 0) ||
|
||||
(partition >= MAXPARTITIONS)) {
|
||||
@ -145,12 +136,12 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
|
||||
}
|
||||
if (*cp && (*cp != ':')) {
|
||||
err = EINVAL;
|
||||
goto fail;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
idev->d_unit = unit;
|
||||
idev->d_kind.disk.slice = slice;
|
||||
idev->d_kind.disk.partition = partition;
|
||||
idev->d_disk.partition = partition;
|
||||
idev->d_disk.data = NULL;
|
||||
if (path != NULL)
|
||||
*path = (*cp == 0) ? cp : cp + 1;
|
||||
break;
|
||||
@ -170,9 +161,7 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
|
||||
err = EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dv->dv_type == DEVT_NET)
|
||||
idev->d_unit = unit;
|
||||
idev->d_unit = unit;
|
||||
|
||||
if (path != NULL)
|
||||
*path = (*cp == 0) ? cp : cp + 1;
|
||||
@ -212,8 +201,6 @@ uboot_fmtdev(void *vdev)
|
||||
case DEVT_DISK:
|
||||
cp = buf;
|
||||
cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_unit);
|
||||
if (dev->d_kind.disk.slice > 0)
|
||||
cp += sprintf(cp, "s%d", dev->d_kind.disk.slice);
|
||||
if (dev->d_kind.disk.partition >= 0)
|
||||
cp += sprintf(cp, "%c", dev->d_kind.disk.partition +
|
||||
'a');
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2000 Benno Rice.
|
||||
* Copyright (c) 2008 Semihalf, Rafal Jaworowski
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -11,99 +11,453 @@
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Block storage I/O routines for U-Boot
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Disk I/O routines using U-Boot - TODO
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <machine/stdarg.h>
|
||||
#include <stand.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#define FSTYPENAMES
|
||||
#include <sys/disklabel.h>
|
||||
|
||||
#include "api_public.h"
|
||||
#include "bootstrap.h"
|
||||
#include "glue.h"
|
||||
#include "libuboot.h"
|
||||
|
||||
static int d_init(void);
|
||||
static int d_strategy(void *devdata, int flag, daddr_t dblk,
|
||||
size_t size, char *buf, size_t *rsize);
|
||||
static int d_open(struct open_file *f, ...);
|
||||
static int d_close(struct open_file *f);
|
||||
static int d_ioctl(struct open_file *f, u_long cmd, void *data);
|
||||
static void d_print(int verbose);
|
||||
#define DEBUG
|
||||
#undef DEBUG
|
||||
|
||||
struct devsw uboot_disk = {
|
||||
"block",
|
||||
#define stor_printf(fmt, args...) do { \
|
||||
printf("%s%d: ", dev->d_dev->dv_name, dev->d_unit); \
|
||||
printf(fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
|
||||
printf(fmt,##args); } while (0)
|
||||
#else
|
||||
#define debugf(fmt, args...)
|
||||
#endif
|
||||
|
||||
struct gpt_part {
|
||||
int gp_index;
|
||||
uuid_t gp_type;
|
||||
uint64_t gp_start;
|
||||
uint64_t gp_end;
|
||||
};
|
||||
|
||||
struct open_dev {
|
||||
int od_bsize; /* block size */
|
||||
int od_bstart; /* start block offset from beginning of disk */
|
||||
int od_type;
|
||||
#define OD_BSDLABEL 0x0001
|
||||
#define OD_GPT 0x0002
|
||||
union {
|
||||
struct {
|
||||
struct disklabel bsdlabel;
|
||||
} _bsd;
|
||||
struct {
|
||||
struct gpt_part *gpt_partitions;
|
||||
int gpt_nparts;
|
||||
} _gpt;
|
||||
} _data;
|
||||
};
|
||||
|
||||
#define od_bsdlabel _data._bsd.bsdlabel
|
||||
#define od_nparts _data._gpt.gpt_nparts
|
||||
#define od_partitions _data._gpt.gpt_partitions
|
||||
|
||||
static int stor_info[UB_MAX_DEV];
|
||||
static int stor_info_no = 0;
|
||||
static int stor_opendev(struct open_dev **, struct uboot_devdesc *);
|
||||
static int stor_closedev(struct uboot_devdesc *);
|
||||
static int stor_readdev(struct uboot_devdesc *, daddr_t, size_t, char *);
|
||||
static int stor_open_count = 0;
|
||||
|
||||
/* devsw I/F */
|
||||
static int stor_init(void);
|
||||
static int stor_strategy(void *, int, daddr_t, size_t, char *, size_t *);
|
||||
static int stor_open(struct open_file *, ...);
|
||||
static int stor_close(struct open_file *);
|
||||
static void stor_print(int);
|
||||
|
||||
struct devsw uboot_storage = {
|
||||
"disk",
|
||||
DEVT_DISK,
|
||||
d_init,
|
||||
d_strategy,
|
||||
d_open,
|
||||
d_close,
|
||||
d_ioctl,
|
||||
d_print
|
||||
stor_init,
|
||||
stor_strategy,
|
||||
stor_open,
|
||||
stor_close,
|
||||
noioctl,
|
||||
stor_print
|
||||
};
|
||||
|
||||
struct opened_dev {
|
||||
u_int count;
|
||||
SLIST_ENTRY(opened_dev) link;
|
||||
};
|
||||
|
||||
SLIST_HEAD(, opened_dev) opened_devs = SLIST_HEAD_INITIALIZER(opened_dev);
|
||||
|
||||
static int
|
||||
d_init(void)
|
||||
stor_init(void)
|
||||
{
|
||||
struct device_info *di;
|
||||
int i, found = 0;
|
||||
|
||||
return 0;
|
||||
if (devs_no == 0) {
|
||||
printf("No U-Boot devices! Really enumerated?\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (i = 0; i < devs_no; i++) {
|
||||
di = ub_dev_get(i);
|
||||
if ((di != NULL) && (di->type & DEV_TYP_STOR)) {
|
||||
if (stor_info_no >= UB_MAX_DEV) {
|
||||
printf("Too many storage devices: %d\n",
|
||||
stor_info_no);
|
||||
return (-1);
|
||||
}
|
||||
stor_info[stor_info_no++] = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
printf("No storage devices\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
debugf("storage devices found: %d\n", stor_info_no);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
d_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf,
|
||||
stor_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf,
|
||||
size_t *rsize)
|
||||
{
|
||||
struct uboot_devdesc *dev = (struct uboot_devdesc *)devdata;
|
||||
struct open_dev *od = (struct open_dev *)dev->d_disk.data;
|
||||
int bcount, err;
|
||||
|
||||
return (EINVAL);
|
||||
debugf("od=%p, size=%d, bsize=%d\n", od, size, od->od_bsize);
|
||||
|
||||
if (rw != F_READ) {
|
||||
stor_printf("write attempt, operation not supported!\n");
|
||||
return (EROFS);
|
||||
}
|
||||
|
||||
if (size % od->od_bsize) {
|
||||
stor_printf("size=%d not multiple of device block size=%d\n",
|
||||
size, od->od_bsize);
|
||||
return (EIO);
|
||||
}
|
||||
bcount = size / od->od_bsize;
|
||||
|
||||
if (rsize)
|
||||
*rsize = 0;
|
||||
|
||||
err = stor_readdev(dev, blk + od->od_bstart, bcount, buf);
|
||||
if (!err && rsize)
|
||||
*rsize = size;
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
d_open(struct open_file *f, ...)
|
||||
stor_open(struct open_file *f, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct open_dev *od;
|
||||
struct uboot_devdesc *dev;
|
||||
int err;
|
||||
|
||||
return (EINVAL);
|
||||
va_start(ap, f);
|
||||
dev = va_arg(ap, struct uboot_devdesc *);
|
||||
va_end(ap);
|
||||
|
||||
if ((err = stor_opendev(&od, dev)) != 0)
|
||||
return (err);
|
||||
|
||||
((struct uboot_devdesc *)(f->f_devdata))->d_disk.data = od;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
d_close(struct open_file *f)
|
||||
stor_close(struct open_file *f)
|
||||
{
|
||||
struct uboot_devdesc *dev;
|
||||
|
||||
return (EINVAL);
|
||||
dev = (struct uboot_devdesc *)(f->f_devdata);
|
||||
|
||||
return (stor_closedev(dev));
|
||||
}
|
||||
|
||||
static int
|
||||
d_ioctl(struct open_file *f, u_long cmd, void *data)
|
||||
stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
|
||||
{
|
||||
|
||||
return (EINVAL);
|
||||
/* TODO */
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
stor_open_bsdlabel(struct open_dev *od, struct uboot_devdesc *dev)
|
||||
{
|
||||
char *buf;
|
||||
struct disklabel *dl;
|
||||
int err = 0;
|
||||
|
||||
/* Allocate 1 block */
|
||||
buf = malloc(od->od_bsize);
|
||||
if (!buf) {
|
||||
stor_printf("could not allocate memory for disklabel\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Read disklabel */
|
||||
err = stor_readdev(dev, LABELSECTOR, 1, buf);
|
||||
if (err) {
|
||||
stor_printf("disklabel read error=%d\n", err);
|
||||
err = ERDLAB;
|
||||
goto out;
|
||||
}
|
||||
bcopy(buf + LABELOFFSET, &od->od_bsdlabel, sizeof(struct disklabel));
|
||||
dl = &od->od_bsdlabel;
|
||||
|
||||
if (dl->d_magic != DISKMAGIC) {
|
||||
stor_printf("no disklabel magic!\n");
|
||||
err = EUNLAB;
|
||||
goto out;
|
||||
}
|
||||
od->od_type = OD_BSDLABEL;
|
||||
od->od_bstart = dl->d_partitions[dev->d_disk.partition].p_offset;
|
||||
|
||||
debugf("bstart=%d\n", od->od_bstart);
|
||||
|
||||
out:
|
||||
free(buf);
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
stor_readdev(struct uboot_devdesc *dev, daddr_t blk, size_t size, char *buf)
|
||||
{
|
||||
lbasize_t real_size;
|
||||
int err, handle;
|
||||
|
||||
debugf("reading size=%d @ 0x%08x\n", size, (uint32_t)buf);
|
||||
|
||||
handle = stor_info[dev->d_unit];
|
||||
err = ub_dev_read(handle, buf, size, blk, &real_size);
|
||||
if (err != 0) {
|
||||
stor_printf("read failed, error=%d\n", err);
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
if (real_size != size) {
|
||||
stor_printf("real size != size\n");
|
||||
err = EIO;
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
stor_opendev(struct open_dev **odp, struct uboot_devdesc *dev)
|
||||
{
|
||||
struct device_info *di;
|
||||
struct open_dev *od;
|
||||
int err, h;
|
||||
|
||||
h = stor_info[dev->d_unit];
|
||||
|
||||
debugf("refcount=%d\n", stor_open_count);
|
||||
|
||||
/*
|
||||
* There can be recursive open calls from the infrastructure, but at
|
||||
* U-Boot level open the device only the first time.
|
||||
*/
|
||||
if (stor_open_count > 0)
|
||||
stor_open_count++;
|
||||
else if ((err = ub_dev_open(h)) != 0) {
|
||||
stor_printf("device open failed with error=%d, handle=%d\n",
|
||||
err, h);
|
||||
*odp = NULL;
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if ((di = ub_dev_get(h)) == NULL)
|
||||
panic("could not retrieve U-Boot device_info, handle=%d", h);
|
||||
|
||||
if ((od = malloc(sizeof(struct open_dev))) == NULL) {
|
||||
stor_printf("could not allocate memory for open_dev\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
od->od_bsize = di->di_stor.block_size;
|
||||
od->od_bstart = 0;
|
||||
od->od_type = 0;
|
||||
|
||||
if ((err = stor_open_gpt(od, dev)) != 0)
|
||||
err = stor_open_bsdlabel(od, dev);
|
||||
|
||||
if (err != 0)
|
||||
free(od);
|
||||
else {
|
||||
stor_open_count = 1;
|
||||
*odp = od;
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
stor_closedev(struct uboot_devdesc *dev)
|
||||
{
|
||||
int err, h;
|
||||
|
||||
free((struct open_dev *)dev->d_disk.data);
|
||||
dev->d_disk.data = NULL;
|
||||
|
||||
if (--stor_open_count == 0) {
|
||||
h = stor_info[dev->d_unit];
|
||||
if ((err = ub_dev_close(h)) != 0) {
|
||||
stor_printf("device close failed with error=%d, "
|
||||
"handle=%d\n", err, h);
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Given a size in 512 byte sectors, convert it to a human-readable number. */
|
||||
/* XXX stolen from sys/boot/i386/libi386/biosdisk.c, should really be shared */
|
||||
static char *
|
||||
display_size(uint64_t size)
|
||||
{
|
||||
static char buf[80];
|
||||
char unit;
|
||||
|
||||
size /= 2;
|
||||
unit = 'K';
|
||||
if (size >= 10485760000LL) {
|
||||
size /= 1073741824;
|
||||
unit = 'T';
|
||||
} else if (size >= 10240000) {
|
||||
size /= 1048576;
|
||||
unit = 'G';
|
||||
} else if (size >= 10000) {
|
||||
size /= 1024;
|
||||
unit = 'M';
|
||||
}
|
||||
sprintf(buf, "%.6ld%cB", (long)size, unit);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
d_print(int verbose)
|
||||
stor_print_bsdlabel(struct uboot_devdesc *dev, char *prefix, int verbose)
|
||||
{
|
||||
char buf[512], line[80];
|
||||
struct disklabel *dl;
|
||||
uint32_t off, size;
|
||||
int err, i, t;
|
||||
|
||||
return;
|
||||
/* Read disklabel */
|
||||
err = stor_readdev(dev, LABELSECTOR, 1, buf);
|
||||
if (err) {
|
||||
sprintf(line, "%s%d: disklabel read error=%d\n",
|
||||
dev->d_dev->dv_name, dev->d_unit, err);
|
||||
pager_output(line);
|
||||
return;
|
||||
}
|
||||
dl = (struct disklabel *)buf;
|
||||
|
||||
if (dl->d_magic != DISKMAGIC) {
|
||||
sprintf(line, "%s%d: no disklabel magic!\n",
|
||||
dev->d_dev->dv_name, dev->d_unit);
|
||||
pager_output(line);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print partitions info */
|
||||
for (i = 0; i < dl->d_npartitions; i++) {
|
||||
if ((t = dl->d_partitions[i].p_fstype) < FSMAXTYPES) {
|
||||
|
||||
off = dl->d_partitions[i].p_offset;
|
||||
size = dl->d_partitions[i].p_size;
|
||||
if (fstypenames[t] == NULL || size == 0)
|
||||
continue;
|
||||
|
||||
if ((('a' + i) == 'c') && (!verbose))
|
||||
continue;
|
||||
|
||||
sprintf(line, " %s%c: %s %s (%d - %d)\n", prefix,
|
||||
'a' + i, fstypenames[t], display_size(size),
|
||||
off, off + size);
|
||||
|
||||
pager_output(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stor_print_one(int i, struct device_info *di, int verbose)
|
||||
{
|
||||
struct uboot_devdesc dev;
|
||||
struct open_dev *od;
|
||||
char line[80];
|
||||
|
||||
sprintf(line, "\tdisk%d (%s)\n", i, ub_stor_type(di->type));
|
||||
pager_output(line);
|
||||
|
||||
dev.d_dev = &uboot_storage;
|
||||
dev.d_unit = i;
|
||||
dev.d_disk.partition = -1;
|
||||
dev.d_disk.data = NULL;
|
||||
|
||||
if (stor_opendev(&od, &dev) == 0) {
|
||||
dev.d_disk.data = od;
|
||||
|
||||
if (od->od_type == OD_GPT) {
|
||||
/* TODO */
|
||||
|
||||
} else if (od->od_type == OD_BSDLABEL) {
|
||||
sprintf(line, "\t\tdisk%d", i);
|
||||
stor_print_bsdlabel(&dev, line, verbose);
|
||||
}
|
||||
|
||||
stor_closedev(&dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stor_print(int verbose)
|
||||
{
|
||||
struct device_info *di;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < stor_info_no; i++) {
|
||||
di = ub_dev_get(stor_info[i]);
|
||||
if (di != NULL)
|
||||
stor_print_one(i, di, verbose);
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ ub_dev_send(int handle, void *buf, int len)
|
||||
return (err);
|
||||
}
|
||||
|
||||
static char *
|
||||
char *
|
||||
ub_stor_type(int type)
|
||||
{
|
||||
|
||||
|
@ -81,5 +81,6 @@ struct device_info *ub_dev_get(int);
|
||||
void ub_dump_di(int);
|
||||
void ub_dump_si(struct sys_info *);
|
||||
char *ub_mem_type(int);
|
||||
char *ub_stor_type(int);
|
||||
|
||||
#endif /* _API_GLUE_H_ */
|
||||
|
@ -27,11 +27,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fully-qualified device descriptor.
|
||||
* Note, this must match the 'struct devdesc' declaration
|
||||
* in bootstrap.h.
|
||||
*/
|
||||
struct uboot_devdesc
|
||||
{
|
||||
struct devsw *d_dev;
|
||||
@ -40,28 +35,29 @@ struct uboot_devdesc
|
||||
union {
|
||||
struct {
|
||||
void *data;
|
||||
int slice;
|
||||
int partition;
|
||||
} disk;
|
||||
} d_kind;
|
||||
};
|
||||
|
||||
#define d_disk d_kind.disk
|
||||
|
||||
/*
|
||||
* Default network packet alignment in memory
|
||||
*/
|
||||
#define PKTALIGN 32
|
||||
|
||||
int uboot_getdev(void **vdev, const char *devspec, const char **path);
|
||||
char *uboot_fmtdev(void *vdev);
|
||||
int uboot_setcurrdev(struct env_var *ev, int flags, const void *value);
|
||||
int uboot_getdev(void **vdev, const char *devspec, const char **path);
|
||||
char *uboot_fmtdev(void *vdev);
|
||||
int uboot_setcurrdev(struct env_var *ev, int flags, const void *value);
|
||||
|
||||
extern int devs_no;
|
||||
extern struct netif_driver uboot_net;
|
||||
extern struct devsw uboot_disk;
|
||||
extern struct devsw uboot_storage;
|
||||
|
||||
ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len);
|
||||
ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len);
|
||||
ssize_t uboot_readin(const int fd, vm_offset_t dest, const size_t len);
|
||||
|
||||
extern int uboot_autoload(void);
|
||||
|
||||
struct preloaded_file;
|
||||
@ -69,4 +65,4 @@ struct file_format;
|
||||
|
||||
extern struct file_format uboot_elf;
|
||||
|
||||
void reboot(void);
|
||||
void reboot(void);
|
||||
|
@ -59,7 +59,6 @@ static int net_get(struct iodesc *, void *, size_t, time_t);
|
||||
static int net_put(struct iodesc *, void *, size_t);
|
||||
static void net_end(struct netif *);
|
||||
|
||||
extern int devs_no;
|
||||
extern struct netif_stats net_stats[];
|
||||
|
||||
struct netif_dif net_ifs[] = {
|
||||
|
@ -52,7 +52,7 @@
|
||||
|
||||
/* XXX these should be defined per controller (or drive) elsewhere, not here! */
|
||||
#if defined(__i386__) || defined(__amd64__) || defined(__arm__) || \
|
||||
defined(__ia64__)
|
||||
defined(__ia64__) || defined(__powerpc__)
|
||||
#define LABELSECTOR 1 /* sector containing label */
|
||||
#define LABELOFFSET 0 /* offset of label in sector */
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user