int md_pre_update(void) { struct mbr_partition *part; mbr_info_t *ext; int i; if (get_ramsize() <= 32) set_swap(diskdev, NULL); read_mbr(diskdev, &mbr); /* do a sanity check of the partition table */ for (ext = &mbr; ext; ext = ext->extended) { part = ext->mbr.mbr_parts; for (i = 0; i < MBR_PART_COUNT; part++, i++) { if (part->mbrp_type != MBR_PTYPE_FAT12) continue; if (part->mbrp_size < (MIN_FAT12_BOOT / 512)) { msg_display(MSG_boottoosmall); msg_display_add(MSG_nobootpart, 0); process_menu(MENU_yesno, NULL); if (!yesno) return 0; nobootfs = 1; } } } if (md_check_partitions() == 0) nobootfs = 1; return 1; }
static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig) { int sector_size; char *mbrbuf_ptr, *mbrbuf_end; u32 buf_base, mbr_base; extern char _end[]; u16 mbr_magic; sector_size = ei->params.bytes_per_sector; if (!sector_size) sector_size = 512; buf_base = (ds() << 4) + (u32)&_end; mbr_base = (buf_base+sector_size-1) & ~(sector_size-1); mbrbuf_ptr = _end + (mbr_base-buf_base); mbrbuf_end = mbrbuf_ptr + sector_size; if (!(boot_params.hdr.loadflags & CAN_USE_HEAP)) return -1; if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr) return -1; memset(mbrbuf_ptr, 0, sector_size); if (read_mbr(devno, mbrbuf_ptr)) return -1; *mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET]; mbr_magic = *(u16 *)&mbrbuf_ptr[510]; return mbr_magic == 0xAA55 ? 0 : -1; }
void rdisk_list_partitions(unsigned char type) { int i,j; int e; struct buf *bp; struct mbr *mbr; for(i=0; i<NRDSK; i++) { e = init_device(i,S_SILENT); if(e!=0) continue; printf("Disk: rd%d: %d KB\n",i,rdsize(makedev(i,0))); bp = read_mbr(i); if(!bp) continue; mbr = (struct mbr *)bp->b_addr; for(j=1; j<5; j++) { if(mbr->partitions[j-1].type==type) { printf(" rd%d%c: %d KB\n",i,'a'+j-1,rdsize(makedev(i,j))); } } brelse(bp); } }
/* * partition_table_get - reads partition table structure from the device * and creates disk description structure * * PARAMETERS: * dev_name - path to physical device in /dev filesystem * disk_desc - returned disc description structure * * RETURNS: * RTEMS_SUCCESSFUL if success, * RTEMS_INTERNAL_ERROR otherwise */ static rtems_status_code partition_table_get(const char *dev_name, rtems_disk_desc_t *disk_desc) { struct stat dev_stat; rtems_status_code rc; int fd; fd = open(dev_name, O_RDONLY); if (fd < 0) { return RTEMS_INTERNAL_ERROR; } rc = fstat(fd, &dev_stat); if (rc != RTEMS_SUCCESSFUL) { close(fd); return RTEMS_INTERNAL_ERROR; } strncpy (disk_desc->dev_name, dev_name, 15); disk_desc->dev = dev_stat.st_rdev; disk_desc->sector_size = (dev_stat.st_blksize) ? dev_stat.st_blksize : RTEMS_IDE_SECTOR_SIZE; rc = read_mbr(fd, disk_desc); close(fd); return rc; }
int md_get_info(void) { struct disklabel disklabel; int fd; char dev_name[100]; if (boardtype == BOARD_TYPE_RPI) return set_bios_geom_with_mbr_guess(); if (pm->no_mbr) return 1; if (read_mbr(pm->diskdev, &mbr) < 0) memset(&mbr.mbr, 0, sizeof(mbr.mbr)-2); if (edit_mbr(&mbr) == 0) return 0; if (strncmp(pm->diskdev, "wd", 2) == 0) pm->disktype = "ST506"; else pm->disktype = "SCSI"; snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev); fd = open(dev_name, O_RDONLY, 0); if (fd < 0) { endwin(); fprintf(stderr, "Can't open %s\n", dev_name); exit(1); } if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { endwin(); fprintf(stderr, "Can't read disklabel on %s.\n", dev_name); close(fd); exit(1); } close(fd); pm->dlcyl = disklabel.d_ncylinders; pm->dlhead = disklabel.d_ntracks; pm->dlsec = disklabel.d_nsectors; pm->sectorsize = disklabel.d_secsize; pm->dlcylsize = disklabel.d_secpercyl; /* * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec) * and secperunit, just in case the disk is already labelled. * (If our new label's RAW_PART size ends up smaller than the * in-core RAW_PART size value, updating the label will fail.) */ pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec; if (disklabel.d_secperunit > pm->dlsize) pm->dlsize = disklabel.d_secperunit; return 1; }
dev_t get_swap_device() { // If a swap device has been specified, then we can short cut all this and just // use that device. #ifdef SWAP return SWAP; #else dev_t bd = -1; int i,j,e; unsigned int max_size = 0; struct buf *bp; struct mbr *mbr; // First we look for the first active swap device for(i=0; i<NRDSK; i++) { e = rdopen(makedev(i,0),0,S_SILENT); if(e==0) { bp = read_mbr(i); if(bp) { mbr = (struct mbr *)bp->b_addr; for(j=0; j<4; j++) { if(mbr->partitions[j].type==RDISK_SWAP) { // If this partition is the biggest so far // then store it. We'll use this if // there is no active partition. if(mbr->partitions[j].lbalength>max_size) { max_size = mbr->partitions[j].lbalength; bd = makedev(i,j+1); } // If it is active, then use it. if(mbr->partitions[j].status & P_ACTIVE) { brelse(bp); rdclose(makedev(i,0),0,0); return makedev(i,j+1); } } } brelse(bp); } rdclose(makedev(i,0),0,0); } } // There is no active partition, so we'll use the biggest one we found. return bd; #endif }
int main(int argc, char const *argv[]) { int i, s, fc, fs, res; const char * n; /* Checking arguments */ s = fc = fs = -1; n = NULL; if (argc < 5) { usage(argv[0]); } for (i = 1; i < argc; i++) { if (!strcmp("-s", argv[i])) { s = strtol(argv[++i], NULL, 10); } else if (!strcmp("-fc", argv[i])) { fc = strtol(argv[++i], NULL, 10); } else if (!strcmp("-fs", argv[i])) { fs = strtol(argv[++i], NULL, 10); } else if (!strcmp("-n", argv[i])) { n = argv[++i]; } else { usage(argv[0]); } } if (s == -1 || fc == -1) { usage(argv[0]); } /* Checking for idiotic input */ if (fc == 0 && fs == 0) { fprintf(stderr, "Wrong input: cannot write on the Master Boot Record, use other values than (0, 0).\n"); } /* Default values */ if (fs == -1) { fs = 0; } /* Start modifying the mbr */ read_mbr(); /* Creating a new volume */ res = create_volume(s, fc, fs, n); display_all_volume_name(); /* End of all modifications, saving them */ save_mbr(); return res; }
static inline int init_device(int root,int flag) { int i; int e; if(root>MAXDEV) return ENODEV; struct buf *bp; struct mbr *mbr; int unit = disks[root].unit; e = disks[root].init(unit,flag); if(e!=0) return e; DEBUG8("rd%d: about to read mbr\n",root); bp = read_mbr(root); if(!bp) return ENXIO; DEBUG8("rd%d: mbr read\n",root); mbr = (struct mbr *)bp->b_addr; DEBUG5("rd%d: partition types: %02X %02X %02X %02X\n",root, mbr->partitions[0].type, mbr->partitions[1].type, mbr->partitions[2].type, mbr->partitions[3].type ); DEBUG8("rd%d: partition 1 start: %p length: %p\n",root, mbr->partitions[0].lbastart, mbr->partitions[0].lbalength ); DEBUG8("rd%d: partition 2 start: %p length: %p\n",root, mbr->partitions[1].lbastart, mbr->partitions[1].lbalength ); DEBUG8("rd%d: partition 3 start: %p length: %p\n",root, mbr->partitions[2].lbastart, mbr->partitions[2].lbalength ); DEBUG8("rd%d: partition 4 start: %p length: %p\n",root, mbr->partitions[3].lbastart, mbr->partitions[3].lbalength ); for(i=0; i<4; i++) { dflags[root].start[i] = mbr->partitions[i].lbastart>>1; dflags[root].len[i] = mbr->partitions[i].lbalength>>1; } dflags[root].blocks = disks[root].size(unit); brelse(bp); return 0; }
void dump_vols(void){ read_mbr(); int i; printf("Volume\tCylindre\tSecteur\tNb blocs\tType\n-----------------------------------------------------------\n"); for (i=0; i<mbr.mbr_n_vol; i++){ printf("sda%d\t%d\t\t%d\t%d\t\t%s\n", i, mbr.mbr_vol[i].vol_first_cylinder, mbr.mbr_vol[i].vol_first_sector, mbr.mbr_vol[i].vol_nblocs, display_type(mbr.mbr_vol[i].vol_type)); } }
static Cyg_ErrNo disk_connected(struct cyg_devtab_entry *tab, cyg_disk_identify_t *ident) { disk_channel *chan = (disk_channel *) tab->priv; cyg_disk_info_t *info = chan->info; Cyg_ErrNo res = ENOERR; //diag_printf("file test:disk_connected\n"); if (!chan->init) {D(("chan->init is false\n"));return -EINVAL;} // If the device is already connected, nothing more to do if( info->connected ) {D(("info->connected is true\n"));return ENOERR;} // If any of these assertions fire, it is probable that the // hardware driver has not been updated to match the current disk // API. CYG_ASSERT( ident->lba_sectors_num > 0, "Bad LBA sector count" ); CYG_ASSERT( ident->phys_block_size > 0, "Bad physical block size"); CYG_ASSERT( ident->max_transfer > 0, "Bad max transfer size"); info->ident = *ident; info->block_size = ident->phys_block_size; info->blocks_num = ident->lba_sectors_num; info->phys_block_size = ident->phys_block_size; D(("disk connected\n")); //D((" serial = '%s'\n", ident->serial)); //D((" firmware rev = '%s'\n", ident->firmware_rev)); //D((" model num = '%s'\n", ident->model_num)); D((" block_size = %d\n", info->block_size)); D((" blocks_num = %u\n", info->blocks_num)); D((" phys_block_size = %d\n", info->phys_block_size)); if (chan->mbr_support) { // read disk master boot record res = read_mbr(chan); } if (ENOERR == res) { // now declare that we are connected info->connected = true; chan->valid = true; } D(("file test:disk_connected end\n")); return res; }
static int dos_get_disk_signature(struct param_d *p, void *_priv) { struct disk_signature_priv *priv = _priv; struct block_device *blk = priv->blk; void *buf; buf = read_mbr(blk); if (!buf) return -EIO; priv->signature = get_unaligned_le32(buf + 0x1b8); free(buf); return 0; }
UINTN showpart(VOID) { UINTN status = 0; UINTN status_gpt, status_mbr; // get full information from disk status_gpt = read_gpt(); status_mbr = read_mbr(); if (status_gpt != 0 || status_mbr != 0) return (status_gpt || status_mbr); // analyze all partitions status = analyze_parts(); if (status != 0) return status; return status; }
dev_t get_boot_device() { // If a root device has been specified, then we can short cut all this and just // use that device. #ifdef ROOT return ROOT; #else dev_t bd = -1; int i,j,e; struct buf *bp; struct mbr *mbr; for(i=0; i<NRDSK; i++) { e = rdopen(makedev(i,0),0,S_SILENT); if(e==0) { bp = read_mbr(i); if(bp) { mbr = (struct mbr *)bp->b_addr; for(j=0; j<4; j++) { if(mbr->partitions[j].type==RDISK_FS) { if(mbr->partitions[j].status & P_ACTIVE) { brelse(bp); rdclose(makedev(i,0),0,0); return makedev(i,j+1); } } } brelse(bp); } rdclose(makedev(i,0),0,0); } } return bd; #endif }
int edit_record(char *device_name, uint64_t offset) { if (offset == 0) { mbr_t mbr; read_mbr(device_name, &mbr); if (OKAY == edit_mbr_loop(&mbr) && are_you_sure() == YES) { write_mbr(device_name, &mbr); } } else { ebr_t ebr; read_ebr(device_name, offset, &ebr); if (OKAY == edit_ebr_loop(&ebr) && are_you_sure() == YES) { write_ebr(device_name, offset, &ebr); } } return OKAY; }
UINTN gptsync(VOID) { UINTN status = 0; UINTN status_gpt, status_mbr; BOOLEAN proceed = FALSE; Print(L"gptsync version %s\ncopyright (c) 2006-2007 Christoph Pfisterer & 2013 Roderick W. Smith\n", VERSION); // get full information from disk status_gpt = read_gpt(); status_mbr = read_mbr(); if (status_gpt != 0 || status_mbr != 0) return (status_gpt || status_mbr); // cross-check current situation Print(L"\n"); status = check_gpt(); // check GPT for consistency if (status != 0) return status; status = check_mbr(); // check MBR for consistency if (status != 0) return status; status = analyze(); // analyze the situation & compose new MBR table if (status != 0) return status; if (new_mbr_part_count == 0) return status; // offer user the choice what to do status = input_boolean(STR("\nMay I update the MBR as printed above? [y/N] "), &proceed); if (status != 0 || proceed != TRUE) return status; // adjust the MBR and write it back status = write_mbr(); if (status != 0) return status; return status; }
static int dos_set_disk_signature(struct param_d *p, void *_priv) { struct disk_signature_priv *priv = _priv; struct block_device *blk = priv->blk; void *buf; __le32 *disksigp; int ret; buf = read_mbr(blk); if (!buf) return -EIO; disksigp = buf + 0x1b8; *disksigp = cpu_to_le32(priv->signature); ret = write_mbr(blk, buf); free(buf); return ret; }
/** Iterate over an extended partition. * @param disk Disk that the partition is on. * @param lba LBA of the extended partition. * @param cb Callback function. */ static void handle_extended(disk_device_t *disk, uint32_t lba, partition_iterate_cb_t cb) { mbr_t *ebr __cleanup_free; size_t i = 4; ebr = malloc(sizeof(*ebr)); for (uint32_t curr_ebr = lba, next_ebr = 0; curr_ebr; curr_ebr = next_ebr) { mbr_partition_t *partition, *next; if (!read_mbr(disk, ebr, curr_ebr)) { dprintf("mbr: failed to read EBR at %" PRIu32 "\n", curr_ebr); break; } else if (ebr->signature != MBR_SIGNATURE) { dprintf("mbr: warning: invalid EBR, corrupt partition table\n"); break; } /* First entry contains the logical partition, second entry refers to * the next EBR, forming a linked list of EBRs. */ partition = &ebr->partitions[0]; next = &ebr->partitions[1]; /* Calculate the location of the next EBR. The start sector is relative * to the start of the extended partition. Set to 0 if the second * partition doesn't refer to another EBR entry, causes the loop to end. */ next->start_lba += lba; next_ebr = (is_valid(disk, next) && is_extended(next) && next->start_lba > curr_ebr) ? next->start_lba : 0; /* Get the partition. Here the start sector is relative to the current * EBR's location. */ partition->start_lba += curr_ebr; if (!is_valid(disk, partition)) continue; cb(disk, i++, partition->start_lba, partition->num_sectors); } }
/** Iterate over the partitions on a device. * @param disk Disk to iterate over. * @param cb Callback function. * @return Whether the device contained an MBR partition table. */ static bool mbr_partition_iterate(disk_device_t *disk, partition_iterate_cb_t cb) { mbr_t *mbr __cleanup_free; bool seen_extended; /* Read in the MBR, which is in the first block on the device. */ mbr = malloc(sizeof(*mbr)); if (!read_mbr(disk, mbr, 0) || mbr->signature != MBR_SIGNATURE) return false; /* Check if this is a GPT partition table (technically we should not get * here if this is a GPT disk as the GPT code should be reached first). This * is just a safeguard. */ if (mbr->partitions[0].type == MBR_PARTITION_TYPE_GPT) return false; /* Loop through all partitions in the table. */ seen_extended = false; for (size_t i = 0; i < array_size(mbr->partitions); i++) { mbr_partition_t *partition = &mbr->partitions[i]; if (!is_valid(disk, partition)) continue; if (is_extended(partition)) { if (seen_extended) { dprintf("mbr: warning: ignoring multiple extended partitions\n"); continue; } handle_extended(disk, partition->start_lba, cb); seen_extended = true; } else { cb(disk, i, partition->start_lba, partition->num_sectors); } } return true; }
unsigned char partition_type(dev_t dev) { struct buf *bp; struct mbr *mbr; unsigned char pt; if (minor(dev)<1 || minor(dev)>4) return 0; if (rdopen(dev,0,S_SILENT) == 0) { bp = read_mbr(major(dev)); rdclose(dev, 0, 0); if (! bp) { brelse(bp); return 0; } mbr = (struct mbr *)bp->b_addr; pt = mbr->partitions[minor(dev)-1].type; brelse(bp); return pt; } return 0; }
UINTN gptsync(int optind, int argc, char **argv) { UINTN status = 0; UINTN status_gpt, status_mbr; BOOLEAN proceed = FALSE; // get full information from disk status_gpt = read_gpt(); status_mbr = read_mbr(); if (status_gpt != 0 || status_mbr != 0) return (status_gpt || status_mbr); // cross-check current situation Print(L"\n"); status = check_gpt(); // check GPT for consistency if (status != 0) return status; status = check_mbr(); // check MBR for consistency if (status != 0) return status; status = analyze(optind, argc, argv); // analyze the situation & compose new MBR table if (status != 0) return status; // offer user the choice what to do status = input_boolean(STR("\nMay I update the MBR as printed above? [y/N] "), &proceed); if (status != 0 || proceed != TRUE) return status; // adjust the MBR and write it back status = write_mbr(); if (status != 0) return status; return status; }
int main(){ int vol; int nom; int nbblocs; int i; unsigned int test_serial = 0xDEADBEEF; init_drive(); read_mbr(); dump_vols(); printf("Saisir le numero du volume:\n"); scanf("%i", &vol); while (mbr.mbr_vol[vol].vol_nblocs == 0){ printf("Veuillez saisir un numero de volume valide:\n"); scanf("%i", &vol); } printf("Saisir le nom:\n"); scanf("%i", &nom); init_super(vol, nom, test_serial); printf("Saisir le nombre de blocs:\n"); scanf("%i", &nbblocs); for (i=0; i<nbblocs; i++){ new_bloc(); } save_super(); if (nbblocs > mbr.mbr_vol[vol].vol_nblocs-1){ nbblocs = mbr.mbr_vol[vol].vol_nblocs-1; } printf("Superbloc rempli de %d blocs !\n", nbblocs); printf("Taux d'occupation : %f/100\n", used_percents(vol)); return 0; }
void kernel_main(uint32_t boot_dev, uint32_t arm_m_type, uint32_t atags) { atag_cmd_line = (void *)0; _atags = atags; _arm_m_type = arm_m_type; UNUSED(boot_dev); // First use the serial console stdout_putc = uart_putc; stderr_putc = uart_putc; stream_putc = def_stream_putc; // Dump ATAGS parse_atags(atags, atag_cb); int result = fb_init(); if(result == 0) puts("Successfully set up frame buffer"); else { puts("Error setting up framebuffer:"); puthex(result); } // Switch to the framebuffer for output stdout_putc = split_putc; printf("Welcome to Rpi bootloader\n"); printf("ARM system type is %x\n", arm_m_type); if(atag_cmd_line != (void *)0) printf("Command line: %s\n", atag_cmd_line); struct usb_hcd *usb_hcd; dwc_usb_init(&usb_hcd, DWC_USB_BASE); struct block_device *sd_dev; if(sd_card_init(&sd_dev) == 0) read_mbr(sd_dev, (void*)0, (void*)0); // List devices printf("MAIN: device list: "); char **devs = vfs_get_device_list(); while(*devs) printf("%s ", *devs++); printf("\n"); // Look for a boot configuration file, starting with the default device, // then iterating through all devices FILE *f = (void*)0; // Default device char **fname = boot_cfg_names; char *found_cfg; while(*fname) { f = fopen(*fname, "r"); if(f) { found_cfg = *fname; break; } fname++; } if(!f) { // Try other devices char **dev = vfs_get_device_list(); while(*dev) { int dev_len = strlen(*dev); fname = boot_cfg_names; while(*fname) { int fname_len = strlen(*fname); char *new_str = (char *)malloc(dev_len + fname_len + 3); new_str[0] = 0; strcat(new_str, "("); strcat(new_str, *dev); strcat(new_str, ")"); strcat(new_str, *fname); f = fopen(new_str, "r"); if(f) { found_cfg = new_str; break; } free(new_str); fname++; } if(f) break; dev++; } } if(!f) { printf("MAIN: No bootloader configuration file found\n"); } else { printf("MAIN: Found bootloader configuration: %s\n", found_cfg); char *buf = (char *)malloc(f->len + 1); buf[f->len] = 0; // null terminate fread(buf, 1, f->len, f); fclose(f); cfg_parse(buf); } }
/* * Boot manager installation/configuration utility. */ int main(int argc, char *argv[]) { u_int8_t *mbr, *boot0; int boot0_size, mbr_size; const char *bpath, *fpath; char *disk; int B_flag, o_flag; int d_arg, m_arg, s_arg, t_arg; int o_and, o_or, o_e = -1; int up, c; bpath = "/boot/boot0"; fpath = NULL; B_flag = v_flag = o_flag = 0; d_arg = m_arg = s_arg = t_arg = -1; o_and = 0xff; o_or = 0; while ((c = getopt(argc, argv, "Bvb:d:e:f:i:m:o:s:t:")) != -1) switch (c) { case 'B': B_flag = 1; break; case 'v': v_flag = 1; break; case 'b': bpath = optarg; break; case 'd': d_arg = argtoi(optarg, 0, 0xff, 'd'); break; case 'e': if (optarg[0] == '0' && optarg[1] == 'x') sscanf(optarg, "0x%02x", &o_e); else o_e = optarg[0]; break; case 'f': fpath = optarg; break; case 'i': if (sscanf(optarg, "%02x%02x-%02x%02x", vol_id, vol_id+1, vol_id+2, vol_id+3) == 4) vol_id[4] = 1; else errx(1, "bad argument %s", optarg); break; case 'm': m_arg = argtoi(optarg, 0, 0xf, 'm'); break; case 'o': stropt(optarg, &o_and, &o_or); o_flag = 1; break; case 's': if (strcasecmp(optarg, "pxe") == 0) s_arg = 6; else s_arg = argtoi(optarg, 1, 6, 's'); break; case 't': t_arg = argtoi(optarg, 1, 0xffff, 't'); break; default: usage(); } argc -= optind; argv += optind; if (argc != 1) usage(); disk = g_device_path(*argv); if (disk == NULL) errx(1, "Unable to get providername for %s\n", *argv); up = B_flag || d_arg != -1 || m_arg != -1 || o_flag || s_arg != -1 || t_arg != -1; /* open the disk and read in the existing mbr. Either here or * when reading the block from disk, we do check for the version * and abort if a suitable block is not found. */ mbr_size = read_mbr(disk, &mbr, !B_flag); /* save the existing MBR if we are asked to do so */ if (fpath) write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size); /* * If we are installing the boot loader, read it from disk and copy the * slice table over from the existing MBR. If not, then point boot0 * back at the MBR we just read in. After this, boot0 is the data to * write back to disk if we are going to do a write. */ if (B_flag) { boot0_size = read_mbr(bpath, &boot0, 1); memcpy(boot0 + OFF_PTBL, mbr + OFF_PTBL, sizeof(struct dos_partition) * NDOSPART); if (b0_ver == 2) /* volume serial number support */ memcpy(boot0 + OFF_SERIAL, mbr + OFF_SERIAL, 4); } else { boot0 = mbr; boot0_size = mbr_size; } /* set the drive */ if (d_arg != -1) boot0[OFF_DRIVE] = d_arg; /* set various flags */ if (m_arg != -1) { boot0[OFF_FLAGS] &= 0xf0; boot0[OFF_FLAGS] |= m_arg; } if (o_flag) { boot0[OFF_FLAGS] &= o_and; boot0[OFF_FLAGS] |= o_or; } /* set the default boot selection */ if (s_arg != -1) boot0[OFF_OPT] = s_arg - 1; /* set the timeout */ if (t_arg != -1) mk2(boot0 + OFF_TICKS, t_arg); /* set the bell char */ if (o_e != -1 && set_bell(boot0, o_e, 0) != -1) up = 1; if (vol_id[4]) { if (b0_ver != 2) errx(1, "incompatible boot block, cannot set volume ID"); boot0[OFF_SERIAL] = vol_id[0]; boot0[OFF_SERIAL+1] = vol_id[1]; boot0[OFF_SERIAL+2] = vol_id[2]; boot0[OFF_SERIAL+3] = vol_id[3]; up = 1; /* force update */ } /* write the MBR back to disk */ if (up) write_mbr(disk, 0, boot0, boot0_size); /* display the MBR */ if (v_flag) display_mbr(boot0); /* clean up */ if (mbr != boot0) free(boot0); free(mbr); free(disk); return 0; }
int main(int argc, char *argv[]) { int rc; int cmd; int done = 0; // Check arguments if (argc == 1) { devname = "/dev/hd0"; } else if (argc == 2) { devname = argv[1]; } else { printf("usage: fdisk <device>\n"); return 1; } // Open device hdev = open(devname, O_RDWR | O_BINARY); if (hdev < 0) { printf("%s: error %d opening device\n", devname, errno); return 1; } // Get disk geometry rc = ioctl(hdev, IOCTL_GETGEOMETRY, &geom , sizeof(struct geometry)); if (rc < 0) { printf("%s: error %d determining disk geometry\n", devname, errno); close(hdev); return 1; } // Read master boot record rc = read_mbr(); if (rc < 0 && errno != EINVAL) { printf("%s: error %d reading master boot record\n", devname, errno); close(hdev); return 1; } // Ask to create new master boot record if the existing is invalid if (rc < 0 && errno == EINVAL) { printf("%s: invalid master boot record\n", devname); if (ask("create new master boot record (y/n)? ", "yn") == 'y') { memcpy(&mbr, bootrecord, sizeof(mbr)); } } // Read commands printf("(a)dd (b)oot (c)ommit (d)elete (l)ist (m)br (h)elp e(x)it\n"); while (!done) { cmd = ask("fdisk> ", "abcdlmhx?"); switch (cmd) { case 'a': add_partition(); break; case 'b': set_boot_part(); break; case 'c': commit_mbr(); break; case 'd': delete_partition(); break; case 'l': list_partitions(); break; case 'm': clear_mbr(); break; case 'h': case '?': help(); break; case 'x': done = 1; break; } } // Close device close(hdev); return 0; }