static PedDisk* bsd_alloc (const PedDevice* dev) { PedDisk* disk; BSDDiskData* bsd_specific; BSDRawLabel* label; PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0); disk = _ped_disk_alloc ((PedDevice*)dev, &bsd_disk_type); if (!disk) goto error; disk->disk_specific = bsd_specific = ped_malloc (sizeof (BSDDiskData)); if (!bsd_specific) goto error_free_disk; /* Initialize the first byte to zero, so that the code in bsd_write knows to call _probe_and_add_boot_code. Initializing all of the remaining buffer is a little wasteful, but the alternative is to figure out why a block at offset 340 would otherwise be used uninitialized. */ memset(bsd_specific->boot_code, 0, sizeof (bsd_specific->boot_code)); label = (BSDRawLabel*) (bsd_specific->boot_code + BSD_LABEL_OFFSET); label->d_magic = PED_CPU_TO_LE32 (BSD_DISKMAGIC); label->d_type = PED_CPU_TO_LE16 (BSD_DTYPE_SCSI); label->d_flags = 0; label->d_secsize = PED_CPU_TO_LE16 (dev->sector_size); label->d_nsectors = PED_CPU_TO_LE32 (dev->bios_geom.sectors); label->d_ntracks = PED_CPU_TO_LE32 (dev->bios_geom.heads); label->d_ncylinders = PED_CPU_TO_LE32 (dev->bios_geom.cylinders); label->d_secpercyl = PED_CPU_TO_LE32 (dev->bios_geom.sectors * dev->bios_geom.heads); label->d_secperunit = PED_CPU_TO_LE32 (dev->bios_geom.sectors * dev->bios_geom.heads * dev->bios_geom.cylinders); label->d_rpm = PED_CPU_TO_LE16 (3600); label->d_interleave = PED_CPU_TO_LE16 (1);; label->d_trackskew = 0; label->d_cylskew = 0; label->d_headswitch = 0; label->d_trkseek = 0; label->d_magic2 = PED_CPU_TO_LE32 (BSD_DISKMAGIC); label->d_bbsize = PED_CPU_TO_LE32 (BSD_BBSIZE); label->d_sbsize = PED_CPU_TO_LE32 (BSD_SBSIZE); label->d_npartitions = 0; label->d_checksum = xbsd_dkcksum (label); return disk; error_free_disk: free (disk); error: return NULL; }
static int bsd_write (const PedDisk* disk) { BSDDiskData* bsd_specific; BSDRawLabel* label; BSDPartitionData* bsd_data; PedPartition* part; int i; int max_part = 0; PED_ASSERT (disk != NULL); PED_ASSERT (disk->dev != NULL); bsd_specific = (BSDDiskData*) disk->disk_specific; label = (BSDRawLabel *) (bsd_specific->boot_code + BSD_LABEL_OFFSET); if (!bsd_specific->boot_code [0]) _probe_and_add_boot_code (disk); memset (label->d_partitions, 0, sizeof (BSDRawPartition) * BSD_MAXPARTITIONS); for (i = 1; i <= BSD_MAXPARTITIONS; i++) { part = ped_disk_get_partition (disk, i); if (!part) continue; bsd_data = part->disk_specific; label->d_partitions[i - 1].p_fstype = bsd_data->type; label->d_partitions[i - 1].p_offset = PED_CPU_TO_LE32 (part->geom.start); label->d_partitions[i - 1].p_size = PED_CPU_TO_LE32 (part->geom.length); max_part = i; } label->d_npartitions = PED_CPU_TO_LE16 (max_part) + 1; label->d_checksum = xbsd_dkcksum (label); alpha_bootblock_checksum (bsd_specific->boot_code); if (!ptt_write_sector (disk, bsd_specific->boot_code, sizeof (BSDDiskData))) goto error; return ped_device_sync (disk->dev); error: return 0; }
int fat_info_sector_generate (FatInfoSector* is, const PedFileSystem* fs) { FatSpecific* fs_info = FAT_SPECIFIC (fs); PED_ASSERT (is != NULL); fat_table_count_stats (fs_info->fat); memset (is, 0, 512); is->signature_1 = PED_CPU_TO_LE32 (FAT32_INFO_MAGIC1); is->signature_2 = PED_CPU_TO_LE32 (FAT32_INFO_MAGIC2); is->free_clusters = PED_CPU_TO_LE32 (fs_info->fat->free_cluster_count); is->next_cluster = PED_CPU_TO_LE32 (fs_info->fat->last_alloc); is->signature_3 = PED_CPU_TO_LE16 (FAT32_INFO_MAGIC3); return 1; }
unsigned int _gen_backup_gpt(gpt_header *g_header,PARTITION_CFG *p_partition_cfg) { unsigned long crc = 0; *(unsigned long long int*)g_header->my_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-1); *(unsigned long long int*)g_header->alternate_lba = PED_CPU_TO_LE64 (1); *(unsigned long long int*)g_header->partition_entry_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-1-MAX_PARTITION_INFO/4); *(unsigned long int*)g_header->header_crc32 = 0; crc = uefi_crc32(g_header,le32_to_int(g_header->header_size)); *(unsigned long int*)g_header->header_crc32 = PED_CPU_TO_LE32(crc); return 1; }
/** * * some internal function for partition * **/ int _gen_pmbr_part(struct partition *part) { part->boot_ind = 0x80; part->sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; part->sector = 1; part->end_head = 0xFF; part->end_sector = 0xFF; part->end_cyl = 0xFF; *(unsigned long int*) part->start_sect = PED_CPU_TO_LE32(1UL); //must get device sector number if ( emmc_part_device.total_sector > 0xFFFFFFF) { *(unsigned long int*) part->nr_sects = PED_CPU_TO_LE32(0xFFFFFFE); } else { *(unsigned long int*) part->nr_sects = PED_CPU_TO_LE32(emmc_part_device.total_sector); } return 1; }
unsigned int _gen_gpt(gpt_header *g_header,PARTITION_CFG *p_partition_cfg) { printf("write gpt header \n"); int i = 0 ,gpt_partition_number = 0; unsigned long crc = 0; _parser_cfg(&gpt_partition_number,p_partition_cfg); *(unsigned long long int*)g_header->signature = PED_CPU_TO_LE64 (GPT_HEADER_SIGNATURE); *(unsigned long int*)g_header->revision = PED_CPU_TO_LE32 (GPT_HEADER_REVISION_V1); *(unsigned long int*)g_header->header_size = PED_CPU_TO_LE32(92UL); *(unsigned long int*)g_header->reserved1 = PED_CPU_TO_LE32(0); *(unsigned long long int*)g_header->my_lba = PED_CPU_TO_LE64 (1); *(unsigned long long int*)g_header->alternate_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-1); *(unsigned long long int*)g_header->first_usable_lba = PED_CPU_TO_LE64 (MAX_PARTITION_INFO/4 + 2); *(unsigned long long int*)g_header->last_usable_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-2-MAX_PARTITION_INFO/4); g_header->disk_guid = _gen_guid(0); *(unsigned long long int*)g_header->partition_entry_lba = PED_CPU_TO_LE64 (2); *(unsigned long int*)g_header->num_partition_entries = PED_CPU_TO_LE32(gpt_partition_number); *(unsigned long int*)g_header->sizeof_partition_entry = PED_CPU_TO_LE32(sizeof(gpt_entry)); memset(g_header->reserved2,0,GPT_BLOCK_SIZE - 92); //_cur_lba_num = MAX_PARTITION_INFO/4 + 2; _cur_lba_num = STARTING_LBA_OF_FIRST_PARTITION; printf("write gpt partition \n"); for(i=0;i<gpt_partition_number;i++) { _gen_gpt_entry(i,&g_gpt_entry_block._gpt_entry[i],p_partition_cfg); } //*(unsigned long int*)g_header->partition_entry_array_crc32 = ; crc = uefi_crc32(&g_gpt_entry_block,(le32_to_int(g_header->num_partition_entries)) *(le32_to_int( g_header->sizeof_partition_entry))); *(unsigned long int*)g_header->partition_entry_array_crc32 = PED_CPU_TO_LE32(crc); //CRC32 check crc = uefi_crc32(g_header,le32_to_int(g_header->header_size)); *(unsigned long int*)g_header->header_crc32 = PED_CPU_TO_LE32(crc); return 1; }
static void _probe_and_add_boot_code (const PedDisk* disk) { void *s0; if (!ptt_read_sector (disk->dev, 0, &s0)) return; char *old_boot_code = s0; BSDRawLabel *old_label = (BSDRawLabel*) (old_boot_code + BSD_LABEL_OFFSET); if (old_boot_code [0] && old_label->d_magic == PED_CPU_TO_LE32 (BSD_DISKMAGIC)) { BSDDiskData *bsd_specific = (BSDDiskData*) disk->disk_specific; memcpy (bsd_specific->boot_code, old_boot_code, sizeof (BSDDiskData)); } free (s0); }
int fat_boot_sector_generate (FatBootSector** bsp, const PedFileSystem* fs) { FatSpecific* fs_info = FAT_SPECIFIC (fs); PED_ASSERT (bsp != NULL); FatBootSector *bs = *bsp; PED_ASSERT (bs != NULL); memcpy (bs->system_id, "MSWIN4.1", 8); bs->sector_size = PED_CPU_TO_LE16 (fs_info->logical_sector_size * 512); bs->cluster_size = fs_info->cluster_sectors / fs_info->logical_sector_size; bs->reserved = PED_CPU_TO_LE16 (fs_info->fat_offset / fs_info->logical_sector_size); bs->fats = fs_info->fat_table_count; bs->dir_entries = (fs_info->fat_type == FAT_TYPE_FAT16) ? PED_CPU_TO_LE16 (fs_info->root_dir_entry_count) : 0; if (fs_info->sector_count / fs_info->logical_sector_size > 0xffff || fs_info->fat_type == FAT_TYPE_FAT32) { bs->sectors = 0; bs->sector_count = PED_CPU_TO_LE32 (fs_info->sector_count / fs_info->logical_sector_size); } else { bs->sectors = PED_CPU_TO_LE16 (fs_info->sector_count / fs_info->logical_sector_size); bs->sector_count = 0; } bs->media = 0xf8; bs->secs_track = PED_CPU_TO_LE16 (fs_info->sectors_per_track); bs->heads = PED_CPU_TO_LE16 (fs_info->heads); bs->hidden = PED_CPU_TO_LE32 (fs->geom->start); if (fs_info->fat_type == FAT_TYPE_FAT32) { bs->fat_length = 0; bs->u.fat32.fat_length = PED_CPU_TO_LE32 (fs_info->fat_sectors / fs_info->logical_sector_size); bs->u.fat32.flags = 0; /* FIXME: what the hell are these? */ bs->u.fat32.version = 0; /* must be 0, for Win98 bootstrap */ bs->u.fat32.root_dir_cluster = PED_CPU_TO_LE32 (fs_info->root_cluster); bs->u.fat32.info_sector = PED_CPU_TO_LE16 (fs_info->info_sector_offset / fs_info->logical_sector_size); bs->u.fat32.backup_sector = PED_CPU_TO_LE16 (fs_info->boot_sector_backup_offset / fs_info->logical_sector_size); bs->u.fat32.drive_num = 0x80; /* _ALWAYS_ 0x80. silly DOS */ memset (bs->u.fat32.empty_1, 0, 12); bs->u.fat32.ext_signature = 0x29; bs->u.fat32.serial_number = PED_CPU_TO_LE32 (fs_info->serial_number); memcpy (bs->u.fat32.volume_name, "NO NAME ", 11); memcpy (bs->u.fat32.fat_name, "FAT32 ", 8); } else { bs->fat_length = PED_CPU_TO_LE16 (fs_info->fat_sectors / fs_info->logical_sector_size); bs->u.fat16.drive_num = 0x80; /* _ALWAYS_ 0x80. silly DOS */ bs->u.fat16.ext_signature = 0x29; bs->u.fat16.serial_number = PED_CPU_TO_LE32 (fs_info->serial_number); memcpy (bs->u.fat16.volume_name, "NO NAME ", 11); memcpy (bs->u.fat16.fat_name, "FAT16 ", 8); } bs->boot_sign = PED_CPU_TO_LE16 (0xaa55); return 1; }
int ext2_metadata_push(struct ext2_fs *fs, blk_t newsize) { int i; int newgdblocks; blk_t newitoffset; newgdblocks = ped_div_round_up (newsize - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb), EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb)); newgdblocks = ped_div_round_up (newgdblocks * sizeof(struct ext2_group_desc), fs->blocksize); newitoffset = newgdblocks + 3; if (newitoffset <= fs->itoffset) return 1; for (i=0;i<fs->numgroups;i++) { blk_t diff; blk_t j; blk_t fromblock; blk_t start; start = (i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb)) + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb); if (EXT2_GROUP_INODE_TABLE(fs->gd[i]) >= start + newitoffset && EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]) >= start + newitoffset - 2 && EXT2_GROUP_INODE_BITMAP(fs->gd[i]) >= start + newitoffset - 1) continue; diff = newitoffset - (EXT2_GROUP_INODE_TABLE(fs->gd[i]) - start); /* inode table */ fromblock = EXT2_GROUP_INODE_TABLE(fs->gd[i]) + fs->inodeblocks; if (fs->opt_debug) { for (j=0;j<diff;j++) if (!ext2_get_block_state(fs, fromblock+j)) { fprintf(stderr, "error: block relocator " "should have relocated " "%i\n", fromblock); return 0; } } for (j=0;j<diff;j++) if (!ext2_set_block_state(fs, fromblock+j, 1, 0)) return 0; if (!ext2_move_blocks(fs, EXT2_GROUP_INODE_TABLE(fs->gd[i]), fs->inodeblocks, EXT2_GROUP_INODE_TABLE(fs->gd[i]) + diff)) return 0; fs->gd[i].bg_inode_table = PED_CPU_TO_LE32 ( EXT2_GROUP_INODE_TABLE(fs->gd[i]) + diff); fs->metadirty |= EXT2_META_GD; if (fs->opt_safe) if (!ext2_sync(fs)) return 0; /* block bitmap and inode bitmap */ fromblock = EXT2_GROUP_INODE_TABLE(fs->gd[i]); if (ext2_is_group_sparse(fs, i)) { if (!ext2_copy_block(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[i]), EXT2_GROUP_INODE_BITMAP(fs->gd[i]) + diff)) return 0; fs->gd[i].bg_inode_bitmap = PED_CPU_TO_LE32 ( EXT2_GROUP_INODE_BITMAP(fs->gd[i]) + diff); fs->metadirty |= EXT2_META_GD; if (fs->opt_safe) if (!ext2_sync(fs)) return 0; if (!ext2_copy_block(fs, EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]), EXT2_GROUP_BLOCK_BITMAP(fs->gd[i])+diff)) return 0; fs->gd[i].bg_block_bitmap = PED_CPU_TO_LE32 ( EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]) + diff); fs->metadirty |= EXT2_META_GD; if (fs->opt_safe) if (!ext2_sync(fs)) return 0; fromblock = EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]); } ext2_zero_blocks(fs, fromblock-diff, diff); for (j=0;j<diff;j++) if (!ext2_set_block_state(fs, fromblock+j-diff, 0, 0)) return 0; if (fs->opt_verbose) fprintf(stderr, "ext2_metadata_push: group %i/%i\r", i+1, fs->numgroups); } fs->itoffset = newitoffset; if (fs->opt_verbose) fputc ('\n', stderr); return 1; }