X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2Fopenhackware%2Fsrc%2Flibpart%2Fcore.c;fp=qemu%2Froms%2Fopenhackware%2Fsrc%2Flibpart%2Fcore.c;h=bc2feb0a49a9e787e30bc7c2177d0b4d5902dc17;hb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;hp=0000000000000000000000000000000000000000;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/qemu/roms/openhackware/src/libpart/core.c b/qemu/roms/openhackware/src/libpart/core.c new file mode 100644 index 000000000..bc2feb0a4 --- /dev/null +++ b/qemu/roms/openhackware/src/libpart/core.c @@ -0,0 +1,288 @@ +/* + * + * + * Open Hack'Ware BIOS partitions management + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License V2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "bios.h" +#include "libpart.h" + +/* Bootable partitions detection and management */ +part_t *part_open (bloc_device_t *bd, + uint32_t start, uint32_t size, uint32_t spb) +{ + part_t *part; + + if (bd_seek(bd, (start + size) * spb, 0) < 0) + return NULL; + part = malloc(sizeof(part_t)); + if (part == NULL) + return NULL; + part->bd = bd; + part->start = start; + part->size = size; + part->spb = spb; + + return part; +} + +int part_seek (part_t *part, uint32_t bloc, uint32_t pos) +{ + if (bloc > part->size) { + ERROR("bloc: %d part size: %d %p\n", bloc, part->size, part); + return -1; + } + bloc += part->start; + if (part->spb != 0) { + bloc *= part->spb; + pos = pos % part->bloc_size; + } else { + pos += (bloc % part->bps) * part->bloc_size; + bloc /= part->bps; + } + + return bd_seek(part->bd, bloc, pos); +} + +int part_read (part_t *part, void *buffer, int len) +{ + return bd_read(part->bd, buffer, len); +} + +int part_write (part_t *part, const void *buffer, int len) +{ + return bd_write(part->bd, buffer, len); +} + +void part_close (part_t *part) +{ + part->size = 0; +} + +uint32_t part_blocsize (part_t *part) +{ + return part->bloc_size; +} + +uint32_t part_flags (part_t *part) +{ + return part->flags; +} + +uint32_t part_size (part_t *part) +{ + return part->size; +} + +fs_t *part_fs (part_t *part) +{ + return part->fs; +} + +void part_private_set (part_t *part, void *private) +{ + part->private = private; +} + +void *part_private_get (part_t *part) +{ + return part->private; +} + +void part_set_blocsize (bloc_device_t *bd, part_t *part, uint32_t blocsize) +{ + uint32_t seclen; + + part->bloc_size = blocsize; + seclen = bd_seclen(bd); + if (blocsize < seclen) { + part->spb = 0; + part->bps = bd_seclen(bd) / part->bloc_size; + DPRINTF("%d part blocs in one sector (%d %d)\n", part->bps, + part->bloc_size, bd_seclen(bd)); + } else { + part->spb = part->bloc_size / bd_seclen(bd); + part->bps = 0; + DPRINTF("%d sectors in one part bloc (%d %d)\n", part->spb, + part->bloc_size, bd_seclen(bd)); + } +} + +int part_register (bloc_device_t *bd, part_t *partition, + const unsigned char *name, int partnum) +{ + part_t **cur; + + DPRINTF("Register partition '%s'\n", name); + partition->bd = bd; + partition->next = NULL; + partition->name = strdup(name); + partition->partnum = partnum; + for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) + continue; + *cur = partition; + + return 0; +} + +part_t *part_get (bloc_device_t *bd, int partnum) +{ + part_t **listp, *cur; + + listp = _bd_parts(bd); + + for (cur = *listp; cur != NULL; cur = cur->next) { + if (cur->partnum == partnum) + break; + } + + return cur; +} + +part_t *part_get_raw (bloc_device_t *bd) +{ + part_t *part; + uint32_t seclen; + + part = malloc(sizeof(part_t)); + part->start = 0; + seclen = bd_seclen(bd); + part->size = bd_maxbloc(bd); + if (seclen > 512) { + part->size *= seclen / 512; + } else { + part->size *= 512 / seclen; + } + part->boot_start.bloc = 0; + part->boot_start.offset = 0; + part->boot_size.bloc = part->size; + part->boot_size.offset = 0; + part->boot_load = 0; + part->boot_entry = 0; + part_set_blocsize(bd, part, 512); + part->bd = bd; + part->flags = PART_TYPE_RAW | PART_FLAG_BOOT; + part_register(bd, part, "Raw", 0); + + return part; +} + +bloc_device_t *part_get_bd (part_t *part) +{ + return part->bd; +} + +part_t *part_probe (bloc_device_t *bd, int set_raw) +{ + part_t *part0 = NULL, *boot_part, **cur; + + /* Try to find a valid boot partition */ + boot_part = Apple_probe_partitions(bd); + if (boot_part == NULL) { + boot_part = isofs_probe_partitions(bd); + if (boot_part == NULL && arch == ARCH_PREP) + boot_part = PREP_find_partition(bd); + if (boot_part == NULL && set_raw != 0) { + dprintf("Use bloc device as raw partition\n"); + } + } + if (_bd_parts(bd) == NULL) { + /* Register the 0 partition: raw partition containing the whole disk */ + part0 = part_get_raw(bd); + } + /* Probe filesystem on each found partition */ + for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) { + const unsigned char *map, *type; + switch ((*cur)->flags & 0x0F) { + case PART_TYPE_PREP: + map = "PREP"; + break; + case PART_TYPE_APPLE: + map = "Apple"; + break; + case PART_TYPE_ISO9660: + map = "ISO9660"; + break; + default: + map = "Raw"; + break; + } + switch ((*cur)->flags & 0xF0) { + case PART_FLAG_DUMMY: + type = "dummy"; + break; + case PART_FLAG_DRIVER: + type = "driver"; + break; + case PART_FLAG_PATCH: + type = "patches"; + break; + case PART_FLAG_FS: + type = "filesystem"; + break; + default: + type = "unknown"; + break; + } + dprintf("Probe filesystem on %s %s partition '%s' %s %p\n", + type, map, (*cur)->name, + ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "", *cur); + if (((*cur)->flags) & PART_FLAG_FS) { + if (((*cur)->flags) & PART_FLAG_BOOT) + (*cur)->fs = fs_probe(*cur, 1); + else + (*cur)->fs = fs_probe(*cur, 0); + } else if (((*cur)->flags) & PART_TYPE_RAW) { + (*cur)->fs = fs_probe(*cur, 2); + } else { + (*cur)->fs = fs_probe(*cur, 2); + } + fs_get_bootfile((*cur)->fs); + if (((*cur)->flags) & PART_FLAG_BOOT) { + dprintf("Partition is bootable (%d)\n", (*cur)->partnum); + bd_set_boot_part(bd, *cur, (*cur)->partnum); + if (boot_part == NULL) + boot_part = *cur; + } + } + dprintf("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs, + part_fs(boot_part), part0); + + return boot_part; +} + +int part_set_boot_file (part_t *part, uint32_t start, uint32_t offset, + uint32_t size) +{ + part->boot_start.bloc = start; + part->boot_start.offset = offset; + part->boot_size.bloc = size; + part->boot_size.offset = 0; + part->boot_load = 0; + part->boot_entry = 0; + part->flags |= PART_FLAG_BOOT; + + return 0; +} + +unsigned int part_get_entry (part_t *part) +{ + return part->boot_entry; +}