Changeset dabe1664 in mainline
- Timestamp:
- 2012-02-21T21:56:11Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9587b37
- Parents:
- 55dbaeb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkexfat/mkexfat.c
r55dbaeb rdabe1664 56 56 #define EBS_SECTOR_START 1 57 57 58 /** First sector of the Main Extended Boot Region Backup */ 59 #define EBS_BACKUP_SECTOR_START 13 60 61 /** First sector of the VBR */ 62 #define VBR_SECTOR 0 63 64 /** First sector if the VBR Backup */ 65 #define VBR_BACKUP_SECTOR 12 66 58 67 /** Size of the Main Extended Boot Region */ 59 68 #define EBS_SIZE 8 … … 64 73 /** The default size of each cluster is 4096 byte */ 65 74 #define DEFAULT_CLUSTER_SIZE 4096 66 67 static unsigned log2(unsigned n);68 75 69 76 typedef struct exfat_cfg { … … 78 85 } exfat_cfg_t; 79 86 87 88 static unsigned log2(unsigned n); 89 90 static uint32_t 91 vbr_checksum_start(void const *octets, size_t nbytes); 92 93 static void 94 vbr_checksum_update(void const *octets, size_t nbytes, uint32_t *checksum); 95 96 static int 97 ebs_write(service_id_t service_id, exfat_cfg_t *cfg, 98 int base, uint32_t *chksum); 99 80 100 static void usage(void) 81 101 { … … 143 163 * @param vbr Pointer to the Volume Boot Record structure. 144 164 * @param cfg Pointer to the exFAT configuration structure. 145 */ 146 static void 165 * @return Initial checksum value. 166 */ 167 static uint32_t 147 168 vbr_initialize(exfat_bs_t *vbr, exfat_cfg_t *cfg) 148 169 { … … 182 203 vbr->allocated_percent = 0; 183 204 vbr->signature = host2uint16_t_le(0xAA55); 205 206 return vbr_checksum_start(vbr, sizeof(exfat_bs_t)); 207 } 208 209 static int 210 bootsec_write(service_id_t service_id, exfat_cfg_t *cfg) 211 { 212 exfat_bs_t vbr; 213 uint32_t vbr_checksum; 214 uint32_t initial_checksum; 215 int rc; 216 217 vbr_checksum = vbr_initialize(&vbr, cfg); 218 initial_checksum = vbr_checksum; 219 220 /* Write the VBR on disk */ 221 rc = block_write_direct(service_id, VBR_SECTOR, 1, &vbr); 222 if (rc != EOK) 223 return rc; 224 225 /* Write the VBR backup on disk */ 226 rc = block_write_direct(service_id, VBR_BACKUP_SECTOR, 1, &vbr); 227 if (rc != EOK) 228 return rc; 229 230 rc = ebs_write(service_id, cfg, EBS_SECTOR_START, &vbr_checksum); 231 if (rc != EOK) 232 return rc; 233 234 /* Restore the checksum to its initial value */ 235 vbr_checksum = initial_checksum; 236 237 return ebs_write(service_id, cfg, EBS_BACKUP_SECTOR_START, &vbr_checksum); 184 238 } 185 239 … … 188 242 * @param service_id The service id. 189 243 * @param cfg Pointer to the exFAT configuration structure. 244 * @param base Base sector of the EBS. 190 245 * @return EOK on success or a negative error code. 191 246 */ 192 247 static int 193 ebs_write(service_id_t service_id, exfat_cfg_t *cfg )248 ebs_write(service_id_t service_id, exfat_cfg_t *cfg, int base, uint32_t *chksum) 194 249 { 195 250 uint32_t *ebs = calloc(cfg->sector_size, sizeof(uint8_t)); 196 251 int i, rc; 252 unsigned idx; 197 253 198 254 if (!ebs) … … 202 258 203 259 for (i = 0; i < EBS_SIZE; ++i) { 204 rc = block_write_direct(service_id, i + EBS_SECTOR_START, 205 1, ebs); 260 vbr_checksum_update(ebs, cfg->sector_size, chksum); 261 262 rc = block_write_direct(service_id, 263 i + EBS_SECTOR_START + base, 1, ebs); 206 264 207 265 if (rc != EOK) 208 266 goto exit; 209 267 } 268 269 /* The OEM record is not yet used 270 * by the official exFAT implementation, we'll fill 271 * it with zeroes. 272 */ 273 274 memset(ebs, 0, cfg->sector_size); 275 vbr_checksum_update(ebs, cfg->sector_size, chksum); 276 277 rc = block_write_direct(service_id, i++ + base, 1, ebs); 278 if (rc != EOK) 279 goto exit; 280 281 /* The next sector is reserved, fill it with zeroes too */ 282 vbr_checksum_update(ebs, cfg->sector_size, chksum); 283 rc = block_write_direct(service_id, i++ + base, 1, ebs); 284 if (rc != EOK) 285 goto exit; 286 287 /* Write the checksum sector */ 288 for (idx = 0; idx < cfg->sector_size / sizeof(uint32_t); ++idx) 289 ebs[idx] = host2uint32_t_le(*chksum); 290 291 rc = block_write_direct(service_id, i + base, 1, ebs); 210 292 211 293 exit: … … 251 333 } 252 334 253 /** Given a power-of-twonumber (n), returns the result of log2(n).335 /** Given a number (n), returns the result of log2(n). 254 336 * 255 337 * It works only if n is a power of two. … … 265 347 } 266 348 349 /** Initialize the VBR checksum calculation */ 350 static uint32_t 351 vbr_checksum_start(void const *data, size_t nbytes) 352 { 353 uint32_t checksum = 0; 354 size_t index; 355 uint8_t const *octets = (uint8_t *) data; 356 357 for (index = 0; index < nbytes; ++index) { 358 if (index == 106 || index == 107 || index == 112) { 359 /* Skip volume_flags and allocated_percent fields */ 360 continue; 361 } 362 363 checksum = ((checksum << 31) | (checksum >> 1)) + octets[index]; 364 } 365 366 return checksum; 367 } 368 369 /** Update the VBR checksum */ 370 static void 371 vbr_checksum_update(void const *data, size_t nbytes, uint32_t *checksum) 372 { 373 size_t index; 374 uint8_t const *octets = (uint8_t *) data; 375 376 for (index = 0; index < nbytes; ++index) 377 *checksum = ((*checksum << 31) | (*checksum >> 1)) + octets[index]; 378 } 379 267 380 int main (int argc, char **argv) 268 381 { 269 382 exfat_cfg_t cfg; 270 exfat_bs_t vbr;271 383 char *dev_path; 272 384 service_id_t service_id; … … 323 435 cfg_params_initialize(&cfg); 324 436 cfg_print_info(&cfg); 325 vbr_initialize(&vbr, &cfg); 326 327 /* Write the VBR on disk */ 328 rc = block_write_direct(service_id, 0, 1, &vbr); 329 if (rc != EOK) { 330 printf(NAME ": Error, failed to write the VBR on disk\n"); 331 return 2; 332 } 333 334 /* Write the VBR backup on disk */ 335 rc = block_write_direct(service_id, 12, 1, &vbr); 336 if (rc != EOK) { 337 printf(NAME ": Error, failed to write the VBR" \ 338 " backup on disk\n"); 339 return 2; 340 } 341 342 rc = ebs_write(service_id, &cfg); 343 if (rc != EOK) { 344 printf(NAME ": Error, failed to write the Main Extended Boot" \ 345 " Sector to disk\n"); 437 438 rc = bootsec_write(service_id, &cfg); 439 if (rc != EOK) { 440 printf(NAME ": Error, failed to write the VBR to disk\n"); 346 441 return 2; 347 442 }
Note:
See TracChangeset
for help on using the changeset viewer.