Changeset 30440ed in mainline
- Timestamp:
- 2013-04-08T23:15:42Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 256cbfe
- Parents:
- 271e24a
- Location:
- uspace
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/hdisk/func_gpt.c
r271e24a r30440ed 35 35 #include <stdio.h> 36 36 #include <errno.h> 37 #include <str_error.h> 37 38 #include <sys/types.h> 38 39 39 40 #include "func_gpt.h" 41 #include "input.h" 42 43 static int set_gpt_partition(tinput_t *, gpt_part_t *); 40 44 41 45 int add_gpt_part(tinput_t * in, union table_data * data) 42 46 { 43 int rc = EOK; 47 gpt_part_t * p = gpt_alloc_partition(data->gpt.parts); 48 if (p == NULL) { 49 return ENOMEM; 50 } 44 51 45 return rc;52 return set_gpt_partition(in, p); 46 53 } 47 54 48 55 int delete_gpt_part(tinput_t * in, union table_data * data) 49 56 { 50 int rc = EOK; 57 size_t idx; 58 59 printf("Number of the partition to delete (counted from 0): "); 60 idx = get_input_size_t(in); 51 61 52 return rc; 62 if (gpt_remove_partition(data->gpt.parts, idx) == -1) { 63 printf("Warning: running low on memory, not resizing...\n"); 64 } 65 66 return EOK; 53 67 } 54 68 55 69 int print_gpt_parts(union table_data * data) 56 70 { 57 int rc = EOK; 71 printf("Current partition scheme (GPT):\n"); 72 printf("\t\tStart:\tEnd:\tLength:\tType:\tName:\n"); 73 74 gpt_foreach(data->gpt.parts, i, iter) { 75 printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length, 76 iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter)); 77 } 58 78 59 79 return rc; … … 62 82 int write_gpt_parts(service_id_t dev_handle, union table_data * data) 63 83 { 64 int rc = EOK;84 int rc; 65 85 66 return rc; 86 rc = gpt_write_partitions(data->gpt.parts, data->gpt.gpt, dev_handle); 87 if (rc != EOK) { 88 printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc)); 89 return rc; 90 } 91 92 rc = gpt_write_gpt_header(data->gpt.gpt, dev_handle); 93 if (rc != EOK) { 94 printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc)); 95 return rc; 96 } 97 98 return EOK; 67 99 } 68 100 101 int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data) 102 { 103 return EOK; 104 } 105 106 static int set_gpt_partition(tinput_t * in, gpt_part_t * p) 107 { 108 int rc; 109 110 uint64_t sa, ea; 111 112 printf("Set starting address (number): "); 113 sa = get_input_uint64(in); 114 115 printf("Set end addres (number): "); 116 ea = get_input_uint64(in); 117 118 if (ea <= sa) { 119 printf("Invalid value.\n"); 120 return EINVAL; 121 } 122 123 124 p->start_addr = sa; 125 p->length = ea - sa; 126 127 return EOK; 128 } 129 -
uspace/app/hdisk/func_gpt.h
r271e24a r30440ed 46 46 extern int print_gpt_parts(union table_data * data); 47 47 extern int write_gpt_parts(service_id_t dev_handle, union table_data * data); 48 extern int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data); 48 49 49 50 #endif -
uspace/app/hdisk/func_mbr.c
r271e24a r30440ed 35 35 #include <stdio.h> 36 36 #include <errno.h> 37 #include <str_error.h> 37 38 #include <sys/types.h> 38 39 … … 94 95 printf(" "); 95 96 96 printf("\t \t%u\t%u\t%u\t%d\n", it->start_addr, it->start_addr + it->length, it->length, it->type);97 printf("\t%10u %10u %10u %3d\n", it->start_addr, it->start_addr + it->length, it->length, it->type); 97 98 98 99 ++num; … … 108 109 int rc = mbr_write_partitions(data->mbr.parts, data->mbr.mbr, dev_handle); 109 110 if (rc != EOK) { 110 printf("Error occured during writing . (ERR: %d)\n", rc);111 printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc)); 111 112 } 112 113 … … 114 115 } 115 116 116 117 int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data) 118 { 119 return EOK; 120 } 117 121 118 122 static int set_mbr_partition(tinput_t * in, mbr_part_t * p) … … 123 127 printf("Primary (p) or logical (l): "); 124 128 c = getchar(); 129 printf("%c\n", c); 125 130 126 131 switch(c) { 127 132 case 'p': 128 133 mbr_set_flag(p, ST_LOGIC, false); 134 break; 129 135 case 'l': 130 136 mbr_set_flag(p, ST_LOGIC, true); 137 break; 131 138 default: 132 139 printf("Invalid type. Cancelled."); … … 144 151 return EINVAL; 145 152 } 146 153 printf("%c\n", c); 147 154 mbr_set_flag(p, ST_BOOT, (c == 'y' || c == 'Y') ? true : false); 148 155 -
uspace/app/hdisk/func_mbr.h
r271e24a r30440ed 46 46 extern int print_mbr_parts(union table_data * data); 47 47 extern int write_mbr_parts(service_id_t dev_handle, union table_data * data); 48 extern int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data); 48 49 49 50 #endif -
uspace/app/hdisk/hdisk.c
r271e24a r30440ed 175 175 return ENOMEM; 176 176 } 177 tinput_set_prompt(in, ""); 177 178 178 179 printf("Welcome to hdisk.\nType 'h' for help.\n"); … … 184 185 while (1) { 185 186 186 //printf("# ");187 printf("# "); 187 188 input = getchar(); 188 //printf("%c\n", input);189 printf("%c\n", input); 189 190 190 191 … … 210 211 table.delete_part(in, &table.data); 211 212 break; 213 case 'e': 214 table.extra_funcs(in, dev_handle, &table.data); 215 break; 212 216 case 'h': 213 217 print_help(); … … 259 263 table.print_parts = print_mbr_parts; 260 264 table.write_parts = write_mbr_parts; 265 table.extra_funcs = extra_mbr_funcs; 261 266 break; 262 267 case LYT_GPT: … … 265 270 table.print_parts = print_gpt_parts; 266 271 table.write_parts = write_gpt_parts; 272 table.extra_funcs = extra_gpt_funcs; 267 273 break; 268 274 default: -
uspace/lib/gpt/libgpt.c
r271e24a r30440ed 117 117 * 118 118 * @return 0 on success, libblock error code otherwise 119 * 120 * Note: Firstly write partitions (if changed), then gpt header. 119 121 */ 120 122 int gpt_write_gpt_header(gpt_t * gpt, service_id_t dev_handle) … … 167 169 unsigned int i; 168 170 gpt_partitions_t * res; 169 uint32_t num_ent = uint32_t_le2host(gpt->raw_data->num_entries);171 uint32_t fill = uint32_t_le2host(gpt->raw_data->fillries); 170 172 uint32_t ent_size = uint32_t_le2host(gpt->raw_data->entry_size); 171 173 uint64_t ent_lba = uint64_t_le2host(gpt->raw_data->entry_lba); 172 174 173 res = alloc_part_array( num_ent);175 res = alloc_part_array(fill); 174 176 if (res == NULL) { 175 177 //errno = ENOMEM; // already set in alloc_part_array() … … 204 206 * will always read just sizeof(gpt_entry_t) bytes - hopefully they 205 207 * don't break backward compatibility) */ 206 for (i = 0; i < num_ent; ++i) {208 for (i = 0; i < fill; ++i) { 207 209 //FIXME: this does bypass cache... 208 210 rc = block_read_bytes_direct(gpt->device, pos, sizeof(gpt_entry_t), res->part_array + i); … … 223 225 * on all of the partition entry array. 224 226 */ 225 uint32_t crc = compute_crc32((uint8_t *) res->part_array, res-> num_ent* sizeof(gpt_entry_t));227 uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->fill * sizeof(gpt_entry_t)); 226 228 227 229 if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc) … … 247 249 size_t b_size; 248 250 249 gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts-> num_ent* gpt->raw_data->entry_size);251 gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->fill * gpt->raw_data->entry_size); 250 252 251 253 rc = block_get_bsize(dev_handle, &b_size); … … 259 261 /* Write to main GPT partition array location */ 260 262 rc = block_write_direct(dev_handle, uint64_t_le2host(gpt->raw_data->entry_lba), 261 nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts-> num_ent) / b_size),263 nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->fill) / b_size), 262 264 parts->part_array); 263 265 if (rc != EOK) … … 277 279 278 280 279 gpt_write_gpt_header(gpt, dev_handle); 280 281 return 0; 282 283 } 284 285 gpt_partitions_t * gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition) 286 { 287 281 return gpt_write_gpt_header(gpt, dev_handle); 282 } 283 284 /** Alloc new partition 285 * 286 * @param parts partition table to carry new partition 287 * 288 * @return returns pointer to the new partition or NULL on ENOMEM 289 * 290 * Note: use either gpt_alloc_partition or gpt_add_partition. The first 291 * returns a pointer to write your data to, the second copies the data 292 * (and does not free the memory). 293 */ 294 gpt_part_t * gpt_alloc_partition(gpt_partitions_t * parts) 295 { 296 if (parts->fill == parts->arr_size) { 297 if (extend_part_array(parts) == -1) 298 return NULL; 299 } 300 301 return parts->part_array + parts->fill++; 302 } 303 304 /** Copy partition into partition array 305 * 306 * @param parts target partition array 307 * @param partition source partition to copy 308 * 309 * @return -1 on error, 0 otherwise 310 * 311 * Note: use either gpt_alloc_partition or gpt_add_partition. The first 312 * returns a pointer to write your data to, the second copies the data 313 * (and does not free the memory). 314 */ 315 int gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition) 316 { 317 if (parts->fill == parts->arr_size) { 318 if (extend_part_array(parts) == -1) 319 return -1; 320 } 288 321 extend_part_array(parts); 289 322 return parts; 290 323 } 291 324 292 gpt_partitions_t * gpt_remove_partition(gpt_partitions_t * parts, size_t idx) 293 { 294 reduce_part_array(parts); 295 return parts; 325 /** Remove partition from array 326 * 327 * @param idx index of the partition to remove 328 * 329 * @return -1 on error, 0 otherwise 330 * 331 * Note: even if it fails, the partition still gets removed. Only 332 * reducing the array failed. 333 */ 334 int gpt_remove_partition(gpt_partitions_t * parts, size_t idx) 335 { 336 if (idx != parts->fill - 1) { 337 memcpy(parts->part_array + idx, parts->part_array + fill - 1, sizeof(gpt_entry_t)); 338 parts->fill -= 1; 339 } 340 341 if (parts->fill < (parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 342 if (reduce_part_array(parts) == -1) 343 return -1; 344 } 345 346 return 0; 296 347 } 297 348 … … 311 362 free(parts->part_array); 312 363 free(parts); 364 } 365 366 /** Get partition type by linear search 367 * (hopefully this doesn't get slow) 368 */ 369 size_t gpt_get_part_type(gpt_part_t * p) 370 { 371 size_t i; 372 for (i = 0; gpt_ptypes[i].guid != NULL; i++) { 373 if (memcmp(p->raw_data.part_type, gpt_ptypes[i].guid, 16) == 0) { 374 break; 375 } 376 } 377 return i; 313 378 } 314 379 … … 343 408 } 344 409 410 char * gpt_get_part_name(gpt_entry_t * p) 411 { 412 return p->raw_data.part_name; 413 } 414 345 415 /** Copy partition name */ 346 416 void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length) 347 417 { 418 if (length >= 72) 419 length = 71; 420 348 421 memcpy(p->part_name, name, length); 422 p->part_name[length] = '\0'; 423 } 424 425 /** Get partition attribute */ 426 extern bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag) 427 { 428 return (p->raw_data.attributes & (((uint64_t) 1) << flag)) ? 1 : 0; 429 } 430 431 /** Set partition attribute */ 432 extern void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value) 433 { 434 uint64_t attr = p->raw_data.attributes; 435 436 if (value) 437 attr = attr | (((uint64_t) 1) << flag); 438 else 439 attr = attr ^ (attr & (((uint64_t) 1) << flag)); 440 441 p->raw_data.attributes = attr; 349 442 } 350 443 … … 405 498 } 406 499 407 res-> num_ent= num;500 res->fill = num; 408 501 res->arr_size = size; 409 502 … … 420 513 } 421 514 422 memcpy(tmp, p->part_array, p-> num_ent);515 memcpy(tmp, p->part_array, p->fill); 423 516 free(p->part_array); 424 517 p->part_array = tmp; … … 438 531 } 439 532 440 memcpy(tmp, p->part_array, p-> num_ent < nsize ? p->num_ent: nsize);533 memcpy(tmp, p->part_array, p->fill < nsize ? p->fill : nsize); 441 534 free(p->part_array); 442 535 p->part_array = tmp; -
uspace/lib/gpt/libgpt.h
r271e24a r30440ed 49 49 /** Basic number of GPT partition entries */ 50 50 #define GPT_BASE_PART_NUM (GPT_MIN_PART_NUM) 51 /** How much fill we ignore before resizing partition array */ 52 #define GPT_IGNORE_FILL_NUM 10 51 53 52 54 /** GPT header signature ("EFI PART" in ASCII) */ 53 55 extern const uint8_t efi_signature[8]; 56 57 typedef enum { 58 AT_REQ_PART = 0, 59 AT_NO_BLOCK_IO, 60 AT_LEGACY_BOOT, 61 AT_UNDEFINED, 62 AT_SPECIFIC = 48 63 } GPT_ATTR; 54 64 55 65 /** GPT header … … 68 78 uint8_t disk_guid[16]; 69 79 uint64_t entry_lba; 70 uint32_t num_entries;80 uint32_t fillries; 71 81 uint32_t entry_size; 72 82 uint32_t pe_array_crc32; … … 105 115 typedef struct gpt_parts { 106 116 /** Number of entries */ 107 unsigned int num_ent;117 size_t fill; 108 118 /** Size of the array */ 109 unsigned int arr_size;119 size_t arr_size; 110 120 /** Resizable partition array */ 111 121 gpt_entry_t * part_array; … … 132 142 extern gpt_partitions_t * gpt_read_partitions(gpt_t * gpt); 133 143 extern int gpt_write_partitions(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle); 134 extern gpt_partitions_t * gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition); 135 extern gpt_partitions_t * gpt_remove_partition(gpt_partitions_t * parts, size_t idx); 136 extern void gpt_set_part_type(gpt_part_t * p, int type); 144 extern gpt_part_t * gpt_alloc_partition(gpt_partitions_t * parts); 145 extern int gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition); 146 extern int gpt_remove_partition(gpt_partitions_t * parts, size_t idx); 147 extern size_t gpt_get_part_type(gpt_part_t * p); 148 extern void gpt_set_part_type(gpt_part_t * p, size_t type); 149 extern char * gpt_get_part_name(gpt_entry_t * p); 137 150 extern void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length); 151 extern bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag); 152 extern void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value); 153 154 #define gpt_foreach(parts, i, iterator) \ 155 for(size_t i = 0, gpt_part_t * iterator = parts->part_array; 156 i < parts->fill; i++, iterator++) 138 157 139 158 extern void gpt_free_gpt(gpt_t * gpt); -
uspace/lib/mbr/Makefile
r271e24a r30440ed 28 28 29 29 USPACE_PREFIX = ../.. 30 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) 30 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -DDEBUG_CONFIG 31 31 LIBRARY = libmbr 32 32 -
uspace/lib/mbr/libmbr.c
r271e24a r30440ed 150 150 return NULL; 151 151 } 152 list_append(&(p->link), &(parts->list));152 //list_append(&(p->link), &(parts->list)); 153 153 p->ebr = NULL; 154 if (decode_part(&(mbr->raw_data.pte[i]), p, 0)) 154 if (decode_part(&(mbr->raw_data.pte[i]), p, 0)) { 155 155 ext = p; 156 parts->l_extended = list_last(&(parts->list)); 157 } 158 mbr_set_flag(p, ST_LOGIC, false); 159 mbr_add_partition(parts, p); 156 160 } 157 161 … … 183 187 184 188 br_block_t * last_ebr = NULL; 185 186 189 link_t * it; 190 191 DEBUG_PRINT_3(LIBMBR_NAME "Writing partitions: n_primary: %u, n_logical:%u, l_extended:%p", parts->n_primary, parts->n_logical, parts->l_extended); 192 187 193 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512); 188 194 if (rc != EOK) { 195 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 189 196 return rc; 190 197 } … … 193 200 goto no_extended; 194 201 195 aoff64_t addr = ext->start_addr; 202 uint32_t base = ext->start_addr; 203 uint32_t addr = base; 204 uint32_t prev_addr; 196 205 mbr_part_t * prev_part = NULL; 197 206 198 list_foreach(parts->list, it ) {199 p = list_get_instance(it , mbr_part_t, link);207 list_foreach(parts->list, iter) { 208 p = list_get_instance(iter, mbr_part_t, link); 200 209 if (mbr_get_flag(p, ST_LOGIC)) { 201 210 // writing logical partition 202 211 212 if (p->start_addr < base || p->start_addr + p->length > base + ext->length) { 213 // out of bounds 214 return EINVAL; 215 } 216 217 203 218 if (p->ebr == NULL) { 204 219 p->ebr = alloc_br(); … … 210 225 } 211 226 212 213 encode_part(p, &(p->ebr->pte[0]), addr); 227 228 229 214 230 if (prev_part != NULL) { 215 encode_part(p, &(prev_part->ebr->pte[1]), ext->start_addr); 216 rc = block_write_direct(dev_handle, p->start_addr, 1, prev_part->ebr); 217 if (rc != EOK) 231 // addr is the address of EBR 232 addr = p->start_addr - base; 233 // base-1 means start_lba+1 234 encode_part(p, &(p->ebr->pte[0]), addr - 1); 235 encode_part(p, &(prev_part->ebr->pte[1]), base); 236 rc = block_write_direct(dev_handle, prev_addr, 1, prev_part->ebr); 237 if (rc != EOK) { 238 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 218 239 goto end; 240 } 241 } else { 242 // addr is the address of EBR 243 addr = base; 244 // base-1 means start_lba+1 245 encode_part(p, &(p->ebr->pte[0]), base - 1); 219 246 } 220 247 221 addr = p->start_addr; 248 //addr = p->start_addr; 249 prev_addr = addr; 222 250 prev_part = p; 223 251 } else { … … 261 289 } 262 290 263 if (rc != EOK) 291 if (rc != EOK) { 292 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 264 293 goto end; 294 } 265 295 266 296 goto skip; … … 268 298 no_extended: 269 299 270 list_foreach(parts->list, it) {300 /*list_foreach(parts->list, it) { 271 301 p = list_get_instance(it, mbr_part_t, link); 272 302 if (mbr_get_flag(p, ST_LOGIC)) { … … 282 312 ++i; 283 313 } 284 } 314 }*/ 315 316 it = parts->list.head.next; 317 for (i = 0; i < N_PRIMARY; i++) { 318 if (it != &parts->list.head) { 319 p = list_get_instance(it, mbr_part_t, link); 320 if (mbr_get_flag(p, ST_LOGIC)) { 321 // extended does not exist, fail 322 return EINVAL; 323 } else { 324 // writing primary partition 325 if (i >= 4) 326 return EINVAL; 327 328 encode_part(p, &(mbr->raw_data.pte[i]), 0); 329 330 } 331 332 it = it->next; 333 } else { 334 encode_part(NULL, &(mbr->raw_data.pte[i]), 0); 335 } 336 } 337 285 338 286 339 skip: 287 340 rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data)); 288 if (rc != EOK) 341 if (rc != EOK) { 342 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 289 343 goto end; 344 } 290 345 291 346 /* … … 382 437 383 438 list_initialize(&(parts->list)); 439 440 parts->n_primary = 0; 441 parts->n_logical = 0; 442 parts->l_extended = NULL; 384 443 385 444 return parts; … … 387 446 388 447 /** Add partition */ 389 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition) 390 { 391 list_append(&(partition->link), &(parts->list)); 448 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p) 449 { 450 list_append(&(p->link), &(parts->list)); 451 if (mbr_get_flag(p, ST_LOGIC)) { 452 parts->n_logical += 1; 453 } else { 454 parts->n_primary += 1; 455 } 456 /* if we're adding new logical partition, we need 1 sector for the EBR 457 * for that partition (including the next one); we'd better make sure here 458 * before writing */ 459 if (mbr_get_flag(p, ST_LOGIC) && p->ebr == NULL) { 460 p->start_addr += 1; 461 p->length -= 1; 462 } 463 //FIXME: we can have multiple extended partitions! :-( 464 392 465 return EOK; 393 466 } … … 396 469 int mbr_remove_partition(mbr_partitions_t * parts, size_t idx) 397 470 { 471 DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %d\n", idx); 398 472 link_t * l = list_nth(&(parts->list), idx); 473 if (l == parts->l_extended) { 474 DEBUG_PRINT_0(LIBMBR_NAME "Removing extended partition.\n"); 475 parts->l_extended = NULL; 476 } 399 477 list_remove(l); 400 478 mbr_part_t * p = list_get_instance(l, mbr_part_t, link); 479 if (mbr_get_flag(p, ST_LOGIC)) { 480 parts->n_logical -= 1; 481 } else { 482 parts->n_primary -= 1; 483 } 484 485 401 486 mbr_free_partition(p); 402 487 … … 448 533 mbr_free_partition(p); 449 534 } 535 536 free(parts); 450 537 } 451 538 … … 465 552 } 466 553 467 /** Parse partition entry to mbr_part_t */ 554 /** Parse partition entry to mbr_part_t 555 * @return returns 1, if extended partition, 0 otherwise 556 * */ 468 557 static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base) 469 558 { … … 480 569 } 481 570 482 /** Parse MBR contents to mbr_part_t list 483 * parameter 'p' is allocated for only used primary partitions 484 */ 571 /** Parse MBR contents to mbr_part_t list */ 485 572 static int decode_logical(mbr_t * mbr, mbr_partitions_t * parts, mbr_part_t * ext) 486 573 { … … 496 583 497 584 498 uint32_t addr= ext->start_addr;499 //uint32_t base = ext->start_addr;585 uint32_t base = ext->start_addr; 586 uint32_t addr = base; 500 587 br_block_t * ebr; 501 588 … … 503 590 if (rc != EOK) 504 591 return rc; 505 506 do { 592 593 ebr = alloc_br(); 594 if (ebr == NULL) { 595 rc = ENOMEM; 596 goto end; 597 } 598 599 rc = block_read_direct(mbr->device, addr, 1, ebr); 600 if (rc != EOK) { 601 goto free_ebr_end; 602 } 603 604 if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) { 605 rc = EINVAL; 606 goto free_ebr_end; 607 } 608 609 if (ebr->pte[0].ptype == PT_UNUSED) { 610 rc = EOK; 611 goto free_ebr_end; 612 } 613 614 p = mbr_alloc_partition(); 615 if (p == NULL) { 616 rc = ENOMEM; 617 goto free_ebr_end; 618 } 619 620 621 decode_part(&(ebr->pte[0]), p, base); 622 mbr_set_flag(p, ST_LOGIC, true); 623 p->ebr = ebr; 624 mbr_add_partition(parts, p); 625 626 addr = uint32_t_le2host(ebr->pte[1].first_lba) + base; 627 628 while (ebr->pte[1].ptype != PT_UNUSED) { 507 629 ebr = alloc_br(); 508 630 if (ebr == NULL) { 509 return ENOMEM; 631 rc = ENOMEM; 632 goto end; 510 633 } 511 634 512 635 rc = block_read_direct(mbr->device, addr, 1, ebr); 513 636 if (rc != EOK) { 514 return rc; 515 } 516 517 //FIXME: is this the right way? 637 goto free_ebr_end; 638 } 639 518 640 if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) { 519 return EINVAL; 641 rc = EINVAL; 642 goto free_ebr_end; 520 643 } 521 644 522 645 p = mbr_alloc_partition(); 523 524 decode_part(&(ebr->pte[0]), p, addr); 646 if (p == NULL) { 647 rc = ENOMEM; 648 goto free_ebr_end; 649 } 650 651 decode_part(&(ebr->pte[0]), p, base); 525 652 mbr_set_flag(p, ST_LOGIC, true); 526 653 p->ebr = ebr; 527 654 mbr_add_partition(parts, p); 528 655 529 //TODO: Check this code 530 addr = ebr->pte[1].first_lba + ext->start_addr; 531 } while (ebr->pte[1].ptype != PT_UNUSED); 532 533 656 addr = uint32_t_le2host(ebr->pte[1].first_lba) + base; 657 } 658 659 rc = EOK; 660 661 free_ebr_end: 662 free(ebr); 663 664 end: 534 665 block_fini(mbr->device); 535 666 536 return EOK;667 return rc; 537 668 } 538 669 … … 543 674 trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE; 544 675 trgt->ptype = src->type; 545 trgt->first_lba = host2uint32_t_le(src->start_addr - base + 63); //63 sectors skipped546 trgt->length = host2uint32_t_le(src->length - 64); //63 + 1 (EBR)676 trgt->first_lba = host2uint32_t_le(src->start_addr - base); 677 trgt->length = host2uint32_t_le(src->length); 547 678 } else { 548 679 trgt->status = 0; -
uspace/lib/mbr/libmbr.h
r271e24a r30440ed 39 39 40 40 #define LIBMBR_NAME "libmbr" 41 42 #ifdef DEBUG_CONFIG 43 #include <stdio.h> 44 #include <str_error.h> 45 #define DEBUG_PRINT_0(str) \ 46 printf("%s:%d: " str, __FILE__, __LINE__) 47 #define DEBUG_PRINT_1(str, arg1) \ 48 printf("%s:%d: " str, __FILE__, __LINE__, arg1) 49 #define DEBUG_PRINT_2(str, arg1, arg2) \ 50 printf("%s:%d: " str, __FILE__, __LINE__, arg1, arg2) 51 #define DEBUG_PRINT_3(str, arg1, arg2, arg3) \ 52 printf("%s:%d: " str, __FILE__, __LINE__, arg1, arg2, arg3) 53 #else 54 #define DEBUG_PRINT_0(str) 55 #define DEBUG_PRINT_1(str, arg1) 56 #define DEBUG_PRINT_2(str, arg1, arg2) 57 #define DEBUG_PRINT_3(str, arg1, arg2, arg3) 58 #endif 41 59 42 60 /** Number of primary partition records */ … … 105 123 /** Device where the data are from */ 106 124 service_id_t device; 107 /** Pointer to partition list */108 //list of partitions; //if we keep this in here, we should free() it in mbr_free_mbr()109 125 } mbr_t; 110 126 111 127 112 //FIXME: make mbr_partitions_t as the linked list for keeping the same interface as with GPT113 128 /** Partition */ 114 129 typedef struct mbr_part { … … 127 142 } mbr_part_t; 128 143 144 /** Partition list structure */ 129 145 typedef struct mbr_parts { 130 146 /** Number of primary partitions */ … … 138 154 } mbr_partitions_t; 139 155 156 /** Both header and partition list */ 140 157 typedef struct mbr_table { 141 158 mbr_t * mbr; … … 151 168 extern int mbr_is_mbr(mbr_t * mbr); 152 169 153 /** Read/Write/Set MBR partitions. */ 170 /** Read/Write/Set MBR partitions. 171 * NOTE: Writing partitions writes the complete header as well. */ 154 172 extern mbr_partitions_t * mbr_read_partitions(mbr_t * mbr); 155 173 extern int mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle);
Note:
See TracChangeset
for help on using the changeset viewer.