/* * Write disk label back to device after modification. */ int writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *osdep) { mbr_args_t a; memset(&a, 0, sizeof a); a.lp = lp; a.strat = strat; /* get a buffer and initialize it */ a.bp = geteblk(2 * (int)lp->d_secsize); a.bp->b_dev = dev; /* osdep => we expect an mbr with label in netbsd ptn */ a.action = osdep != NULL ? WRITE_LABEL : UPDATE_LABEL; /* Write/update the label to every netbsd mbr partition */ scan_mbr(&a, write_netbsd_label); /* Old write the label at the start of the volume on disks that * don't have a valid mbr (always update an existing one) */ a.action = a.found_mbr ? UPDATE_LABEL : WRITE_LABEL; validate_label(&a, 0); if (a.written == 0 && a.error == 0) a.error = ESRCH; brelse(a.bp, 0); return a.error; }
static int look_netbsd_part(mbr_args_t *a, mbr_partition_t *dp, int slot, uint ext_base) { struct partition *pp; int ptn_base = ext_base + le32toh(dp->mbrp_start); int rval; if ( #ifdef COMPAT_386BSD_MBRPART dp->mbrp_type == MBR_PTYPE_386BSD || #endif dp->mbrp_type == MBR_PTYPE_NETBSD) { rval = validate_label(a, ptn_base); #if RAW_PART == 3 /* Put actual location where we found the label into ptn 2 */ if (rval == SCAN_FOUND || a->lp->d_partitions[2].p_size == 0) { a->lp->d_partitions[2].p_size = le32toh(dp->mbrp_size); a->lp->d_partitions[2].p_offset = ptn_base; } #endif /* If we got a netbsd label look no further */ if (rval == SCAN_FOUND) return rval; } /* Install main partitions into e..h and extended into i+ */ if (ext_base == 0) slot += 4; else { slot = 4 + MBR_PART_COUNT; pp = &a->lp->d_partitions[slot]; for (; slot < MAXPARTITIONS; pp++, slot++) { /* This gets called twice - avoid duplicates */ if (pp->p_offset == ptn_base && pp->p_size == le32toh(dp->mbrp_size)) break; if (pp->p_size == 0) break; } } if (slot < MAXPARTITIONS) { /* Stop 'a' being the entire disk */ a->lp->d_partitions[0].p_size = 0; a->lp->d_partitions[0].p_fstype = 0; /* save partition info */ pp = &a->lp->d_partitions[slot]; pp->p_offset = ptn_base; pp->p_size = le32toh(dp->mbrp_size); pp->p_fstype = xlat_mbr_fstype(dp->mbrp_type); if (slot >= a->lp->d_npartitions) a->lp->d_npartitions = slot + 1; } return SCAN_CONTINUE; }
static int write_netbsd_label(mbr_args_t *a, mbr_partition_t *dp, int slot, uint ext_base) { int ptn_base = ext_base + le32toh(dp->mbrp_start); if (dp->mbrp_type != MBR_PTYPE_NETBSD) return SCAN_CONTINUE; return validate_label(a, ptn_base); }
static int look_netbsd_part(mbr_args_t *a, struct mbr_partition *dp, int slot, u_int ext_base) { int ptn_base = ext_base + le32toh(dp->mbrp_start); int rval; if ( #ifdef COMPAT_386BSD_MBRPART dp->mbrp_type == MBR_PTYPE_386BSD || #endif dp->mbrp_type == MBR_PTYPE_NETBSD) { rval = validate_label(a, ptn_base + BSD44_MBR_LABELSECTOR, 0); /* If we got a NetBSD label, look no further. */ if (rval == SCAN_FOUND) return (rval); } return (SCAN_CONTINUE); }
static int dkwedge_discover_bsdlabel(struct disk *pdk, struct vnode *vp) { mbr_args_t a; const struct disklabel_location *dl; int rval; a.pdk = pdk; a.vp = vp; a.buf = DKW_MALLOC(DEV_BSIZE); a.error = 0; /* MBR search. */ rval = scan_mbr(&a, look_netbsd_part); if (rval != SCAN_CONTINUE) { if (rval == SCAN_FOUND) a.error = 0; /* found it, wedges installed */ goto out; } /* Known location search. */ for (dl = disklabel_locations; dl->label_sector != -1; dl++) { rval = validate_label(&a, dl->label_sector, dl->label_offset); if (rval != SCAN_CONTINUE) { if (rval == SCAN_FOUND) a.error = 0; /* found it, wedges installed */ goto out; } } /* No NetBSD disklabel found. */ a.error = ESRCH; out: DKW_FREE(a.buf); return (a.error); }
/** Parse text file and create * list elements for each instruction * appends instructions to the end of the list it gets * so that you can call this more than once, to include * more than one file * if you call it passing a root that is null, it will return * the beginning of the list * if you pass it something other than null, it returns a pointer * to the last link of the list */ struct instruction *parse_source(FILE *infile, struct instruction* initial_root, struct tab_entry *tabroot) { struct instruction *cur_old =NULL, *cur = NULL; struct instruction *inst_root; char buffer[INSTRUCTION_BUFFER_SIZE]; char b[INSTRUCTION_BUFFER_SIZE]; char *buf, *ptr; int instructions = 0; int cur_op_num; inst_root = initial_root; buf = b; while (fgets(buffer, INSTRUCTION_BUFFER_SIZE, infile)) { strip_comment(buffer); linenumber++; if (cur == NULL) cur = new_instruction(); if (isblank(buffer[0]) || (buffer[0] == '\n') || (buffer[0] == '#') || (buffer[0] == '.')) { if (buffer[0] == '#') //make preprocessor directives .<directive> buffer[0] = '.'; /** split line, get instruction and operands */ if ((buf = (char *) strtok(buffer, whitespace))) { instructions++; if (!inst_root) inst_root = cur; if (cur_old) cur_old->next = cur; capitalize(buf); strncpy(cur->mnumonic, buf, MNUMONIC_TXT_LENGTH); get_operands(cur); } calculate_opcode(tabroot, cur); cur_old = cur; cur = new_instruction(); } else { /* see if it's a valid label */ if (strlen(buffer) > 0) { if ((buf = (char *) strtok(buffer, whitespace))) { instructions++; if (!inst_root) inst_root = cur; if (cur_old) cur_old->next = cur; capitalize(buf); strncpy(cur->mnumonic, buf, MNUMONIC_TXT_LENGTH); get_operands(cur); } // buffer holds untokenized string with charcter at *[0] if (validate_label(buffer)) { add_label(buffer, cur); } else { do_error_msg(ERR_BADLABEL); } } } } /* return either the head or the tail */ return initial_root == NULL ? inst_root : cur; }
/* * Attempt to read a disk label from a device * using the indicated strategy routine. * The label must be partly set up before this: * secpercyl, secsize and anything required for a block i/o read * operation in the driver's strategy/start routines * must be filled in before calling us. * * If dos partition table requested, attempt to load it and * find disklabel inside a DOS partition. Also, if bad block * table needed, attempt to extract it as well. Return buffer * for use in signalling errors if requested. * * Returns null on success and an error string on failure. */ const char * readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *osdep) { struct dkbad *bdp; int rval; int i; mbr_args_t a; memset(&a, 0, sizeof a); a.lp = lp; a.strat = strat; a.action = READ_LABEL; /* minimal requirements for architypal disk label */ if (lp->d_secsize == 0) lp->d_secsize = DEV_BSIZE; if (lp->d_secperunit == 0) lp->d_secperunit = 0x1fffffff; a.secperunit = lp->d_secperunit; lp->d_npartitions = RAW_PART + 1; for (i = 0; i < RAW_PART; i++) { lp->d_partitions[i].p_size = 0; lp->d_partitions[i].p_offset = 0; } if (lp->d_partitions[RAW_PART].p_size == 0) lp->d_partitions[RAW_PART].p_size = lp->d_secperunit; lp->d_partitions[RAW_PART].p_offset = 0; /* * Set partition 'a' to be the whole disk. * Cleared if we find an mbr or a netbsd label. */ lp->d_partitions[0].p_size = lp->d_partitions[RAW_PART].p_size; lp->d_partitions[0].p_fstype = FS_BSDFFS; /* get a buffer and initialize it */ a.bp = geteblk(2 * (int)lp->d_secsize); a.bp->b_dev = dev; if (osdep) /* * Scan mbr searching for netbsd partition and saving * bios partition information to use if the netbsd one * is absent. */ rval = scan_mbr(&a, look_netbsd_part); else rval = SCAN_CONTINUE; if (rval == SCAN_CONTINUE) { /* Look at start of disk */ rval = validate_label(&a, 0); } #if 0 /* * Save sector where we found the label for the 'don't overwrite * the label' check in bounds_check_with_label. */ if (rval == SCAN_FOUND) xxx->label_sector = a.label_sector; #endif /* Obtain bad sector table if requested and present */ if (rval == SCAN_FOUND && osdep && (lp->d_flags & D_BADSECT)) { struct dkbad *db; int blkno; bdp = &osdep->bad; i = 0; rval = SCAN_ERROR; do { /* read a bad sector table */ blkno = lp->d_secperunit - lp->d_nsectors + i; if (lp->d_secsize > DEV_BSIZE) blkno *= lp->d_secsize / DEV_BSIZE; else blkno /= DEV_BSIZE / lp->d_secsize; /* if successful, validate, otherwise try another */ if (read_sector(&a, blkno, 1)) { a.msg = "bad sector table I/O error"; continue; } db = (struct dkbad *)(a.bp->b_data); #define DKBAD_MAGIC 0x4321 if (db->bt_mbz != 0 || db->bt_flag != DKBAD_MAGIC) { a.msg = "bad sector table corrupted"; continue; } rval = SCAN_FOUND; *bdp = *db; break; } while (a.bp->b_error && (i += 2) < 10 && i < lp->d_nsectors); } brelse(a.bp, 0); if (rval == SCAN_ERROR || rval == SCAN_CONTINUE) return a.msg; return NULL; }