Changeset 7570e800 in mainline


Ignore:
Timestamp:
2012-12-18T23:05:20Z (12 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5beb1ff
Parents:
cbd64057
Message:

libgpt update

Location:
uspace/lib
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    rcbd64057 r7570e800  
    6666        generic/cap.c \
    6767        generic/cfg.c \
     68        generic/checksum.c \
    6869        generic/clipboard.c \
    6970        generic/devman.c \
  • uspace/lib/gpt/libgpt.c

    rcbd64057 r7570e800  
    3838 */
    3939
     40#include <ipc/bd.h>
     41#include <async.h>
     42#include <stdio.h>
     43#include <block.h>
     44#include <errno.h>
     45#include <stdlib.h>
     46#include <assert.h>
     47#include <byteorder.h>
    4048#include <checksum.h>
    41 #include <errno.h>
    4249#include <mem.h>
    4350
    4451#include "libgpt.h"
     52
     53static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header);
     54static gpt_parts_t * alloc_part_array(uint32_t num);
     55static int extend_part_array(gpt_parts_t * p);
     56static int reduce_part_array(gpt_parts_t * p);
     57static long long nearest_larger_int(double a);
    4558
    4659/** Read GPT from specific device
     
    6679        }
    6780       
    68         gpt->header_lba = malloc(b_size);// We might need only sizeof(gpt_header_t),
     81        gpt->raw_data = malloc(b_size);// We might need only sizeof(gpt_header_t),
    6982        if (gpt == NULL) {                              // but we should follow specs and have
    7083                free(gpt);                                      // zeroes through all the rest of the block
     
    7487       
    7588       
    76         rc = load_and_check_header(handle, GPT_HDR_BA, gpt->header_lba);
     89        rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, gpt->raw_data);
    7790        if (rc == EBADCHECKSUM || rc == EINVAL) {
    7891                aoff64_t n_blocks;
     
    8396                }
    8497               
    85                 rc = load_and_check_header(handle, n_blocks - 1, gpt->header_lba);
     98                rc = load_and_check_header(dev_handle, n_blocks - 1, b_size, gpt->raw_data);
    8699                if (rc == EBADCHECKSUM || rc == EINVAL) {
    87100                        errno = rc;
     
    90103        }
    91104       
     105        gpt->device = dev_handle;
     106       
    92107        return gpt;
    93108
     
    103118 * @return                              0 on success, libblock error code otherwise
    104119 */
    105 int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle)
     120int gpt_write_gpt_header(gpt_t * gpt, service_id_t dev_handle)
    106121{
    107122        int rc;
    108123        size_t b_size;
    109124       
    110         header->raw_data->header_crc32 = 0;
    111         header->raw_data->header_crc32 = compute_crc32(header, header->header_size);
     125        gpt->raw_data->header_crc32 = 0;
     126        gpt->raw_data->header_crc32 = compute_crc32((uint8_t *) gpt->raw_data,
     127                                        uint32_t_le2host(gpt->raw_data->header_size));
    112128       
    113129        rc = block_get_bsize(dev_handle, &b_size);
     
    120136       
    121137        /* Write to main GPT header location */
    122         rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, header->raw_data);
     138        rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, gpt->raw_data);
    123139        if (rc != EOK)
    124140                block_fini(dev_handle);
     
    131147       
    132148        /* Write to backup GPT header location */
    133         rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
     149        //FIXME: those idiots thought it would be cool to have these fields in reverse order...
     150        rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, gpt->raw_data);
    134151        block_fini(dev_handle);
    135152        if (rc != EOK)
     
    147164gpt_parts_t * gpt_read_partitions(gpt_t * gpt)
    148165{
    149         int i;
     166        int rc;
     167        unsigned int i;
    150168        gpt_parts_t * res;
    151         uint32_t num_ent = uint32_t_le2host(gpt->header.num_entries);
    152         uint32_t ent_size = uint32_t_le2host(gpt->header.entry_size);
    153         uint64_t ent_lba = uint64_t_le2host(gpt->header.entry_lba);
     169        uint32_t num_ent = uint32_t_le2host(gpt->raw_data->num_entries);
     170        uint32_t ent_size = uint32_t_le2host(gpt->raw_data->entry_size);
     171        uint64_t ent_lba = uint64_t_le2host(gpt->raw_data->entry_lba);
    154172       
    155173        res = alloc_part_array(num_ent);
     
    162180         *  - we don't need more bytes
    163181         *  - the size of GPT partition entry can be different to 128 bytes */
    164         rc = block_init(EXCHANGE_SERIALIZE, dev_handle, sizeof(gpt_entry_t));
     182        rc = block_init(EXCHANGE_SERIALIZE, gpt->device, sizeof(gpt_entry_t));
    165183        if (rc != EOK) {
    166184                gpt_free_partitions(res);
     
    200218        }
    201219       
    202         uint32_t crc = compute_crc32(res->part_array, res->num_ent * sizeof(gpt_entry_t));
    203        
    204         if(gpt->raw_data.pe_array_crc32 != crc)
     220        /* FIXME: so far my boasting about variable partition entry size
     221         * will not work. The CRC32 checksums will be different.
     222         * This can't be fixed easily - we'd have to run the checksum
     223         * on all of the partition entry array.
     224         */
     225        uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->num_ent * sizeof(gpt_entry_t));
     226       
     227        if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc)
    205228        {
    206229                gpt_free_partitions(res);
     
    214237/** Write GPT and partitions to device
    215238 * @param parts                 partition list to be written
    216  * @param mbr                   MBR to be written with 'parts' partitions
     239 * @param header                GPT header belonging to the 'parts' partitions
    217240 * @param dev_handle    device to write the data to
    218241 *
    219242 * @return                              returns EOK on succes, specific error code otherwise
    220243 */
    221 int gpt_write_partitions(gpt_parts_t * parts, gpt_t * header, service_id_t dev_handle)
    222 {
    223         int i;
     244int gpt_write_partitions(gpt_parts_t * parts, gpt_t * gpt, service_id_t dev_handle)
     245{
     246        int rc;
    224247        size_t b_size;
    225248       
    226         header->raw_data->pe_array_crc32 = compute_crc32(parts->part_array, parts->num_ent * header->raw_data->entry_size);
     249        gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->num_ent * gpt->raw_data->entry_size);
    227250       
    228251        rc = block_get_bsize(dev_handle, &b_size);
     
    235258       
    236259        /* Write to main GPT partition array location */
    237         rc = block_write_direct(dev_handle, uint64_t_le2host(header->entry_lba),
    238                         nearest_larger_int((uint64_t_le2host(header->raw_data->entry_size) * parts->num_ent) / b_size),
     260        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),
    239262                        parts->part_array);
    240263        if (rc != EOK)
     
    254277       
    255278       
    256         gpt_write_gpt_header(header, dev_handle);
     279        gpt_write_gpt_header(gpt, dev_handle);
    257280       
    258281        return 0;
     282       
     283}
     284
     285gpt_parts_t * gpt_add_partition(gpt_parts_t * parts, g_part_t * partition)
     286{
     287       
     288}
     289
     290gpt_parts_t * gpt_remove_partition(gpt_parts_t * parts, int idx)
     291{
    259292       
    260293}
     
    263296void gpt_free_gpt(gpt_t * gpt)
    264297{
    265         free(gpt->header_lba);
     298        free(gpt->raw_data);
    266299        free(gpt);
    267300}
     
    286319{
    287320        /* Beware: first 3 blocks are byteswapped! */
    288         p->raw_data.part_type[3] = gpt_ptypes[type][0];
    289         p->raw_data.part_type[2] = gpt_ptypes[type][1];
    290         p->raw_data.part_type[1] = gpt_ptypes[type][2];
    291         p->raw_data.part_type[0] = gpt_ptypes[type][3];
    292        
    293         p->raw_data.part_type[5] = gpt_ptypes[type][4];
    294         p->raw_data.part_type[4] = gpt_ptypes[type][5];
    295        
    296         p->raw_data.part_type[7] = gpt_ptypes[type][6];
    297         p->raw_data.part_type[6] = gpt_ptypes[type][7];
    298        
    299         p->raw_data.part_type[8] = gpt_ptypes[type][8];
    300         p->raw_data.part_type[9] = gpt_ptypes[type][9];
    301         p->raw_data.part_type[10] = gpt_ptypes[type][10];
    302         p->raw_data.part_type[11] = gpt_ptypes[type][11];
    303         p->raw_data.part_type[12] = gpt_ptypes[type][12];
    304         p->raw_data.part_type[13] = gpt_ptypes[type][13];
    305         p->raw_data.part_type[14] = gpt_ptypes[type][14];
    306         p->raw_data.part_type[15] = gpt_ptypes[type][15];
     321        p->raw_data.part_type[3] = gpt_ptypes[type].guid[0];
     322        p->raw_data.part_type[2] = gpt_ptypes[type].guid[1];
     323        p->raw_data.part_type[1] = gpt_ptypes[type].guid[2];
     324        p->raw_data.part_type[0] = gpt_ptypes[type].guid[3];
     325       
     326        p->raw_data.part_type[5] = gpt_ptypes[type].guid[4];
     327        p->raw_data.part_type[4] = gpt_ptypes[type].guid[5];
     328       
     329        p->raw_data.part_type[7] = gpt_ptypes[type].guid[6];
     330        p->raw_data.part_type[6] = gpt_ptypes[type].guid[7];
     331       
     332        p->raw_data.part_type[8] = gpt_ptypes[type].guid[8];
     333        p->raw_data.part_type[9] = gpt_ptypes[type].guid[9];
     334        p->raw_data.part_type[10] = gpt_ptypes[type].guid[10];
     335        p->raw_data.part_type[11] = gpt_ptypes[type].guid[11];
     336        p->raw_data.part_type[12] = gpt_ptypes[type].guid[12];
     337        p->raw_data.part_type[13] = gpt_ptypes[type].guid[13];
     338        p->raw_data.part_type[14] = gpt_ptypes[type].guid[14];
     339        p->raw_data.part_type[15] = gpt_ptypes[type].guid[15];
    307340}
    308341
    309342/** Copy partition name */
    310 void gpt_set_part_name(gpt_entry_t * p, char_t name[], size_t length)
     343void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length)
    311344{
    312345        memcpy(p->part_name, name, length);
     
    315348// Internal functions follow //
    316349
    317 static int load_and_check_header(service_id_t handle, aoff64_t addr, gpt_t * header)
    318 {
    319         rc = block_init(EXCHANGE_ATOMIC, handle, b_size);
    320         if (rc != EOK)
    321                 return rc;
    322        
    323         rc = block_read_direct(handle, addr, GPT_HDR_BS, gpt->header_lba);
    324         block_fini(handle);
    325         if (rc != EOK)
    326                 return rc;
    327        
    328        
    329         int i;
     350static int load_and_check_header(service_id_t dev_handle, aoff64_t addr, size_t b_size, gpt_header_t * header)
     351{
     352        int rc;
     353       
     354        rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
     355        if (rc != EOK)
     356                return rc;
     357       
     358        rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
     359        block_fini(dev_handle);
     360        if (rc != EOK)
     361                return rc;
     362       
     363       
     364        unsigned int i;
    330365        /* Check the EFI signature */
    331366        for (i = 0; i < 8; ++i) {
    332                 if (gpt->header_lba.efi_signature[i] != efi_signature[i])
     367                if (header->efi_signature[i] != efi_signature[i])
    333368                        return EINVAL;
    334369        }
    335370       
    336371        /* Check the CRC32 of the header */
    337         uint32_t crc = gpt->header_lba->header_crc32;
    338         gpt->header_lba->header_crc32 = 0;
    339         if (crc != compute_crc32(gpt->header_lba, gpt->header_lba->header_size))
     372        uint32_t crc = header->header_crc32;
     373        header->header_crc32 = 0;
     374        if (crc != compute_crc32((uint8_t *) header, header->header_size))
    340375                return EBADCHECKSUM;
    341376        else
    342                 gpt->header_lba->header_crc32 = crc;
     377                header->header_crc32 = crc;
    343378       
    344379        /* Check for zeroes in the rest of the block */
    345380        for (i = sizeof(gpt_header_t); i < b_size; ++i) {
    346                 if (((uint8_t *) gpt->header_lba)[i] != 0)
    347                         goto EINVAL;
    348         }
    349        
    350         gpt->device = dev_handle;
    351         //gpt->partitions = NULL;
    352        
     381                if (((uint8_t *) header)[i] != 0)
     382                        return EINVAL;
     383        }
     384               
    353385        return EOK;
    354386}
     
    364396        uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
    365397        res->part_array = malloc(size * sizeof(gpt_entry_t));
    366         if (res.part_array == NULL) {
     398        if (res->part_array == NULL) {
    367399                free(res);
    368400                errno = ENOMEM;
  • uspace/lib/gpt/libgpt.h

    rcbd64057 r7570e800  
    3636#define __GPT_H__
    3737
     38#define NAME    "libgpt"
     39
    3840#include <sys/types.h>
    3941
     
    5254};
    5355
    54 /** GPT header */
     56/** GPT header
     57 * - all in little endian.
     58 */
    5559typedef struct {
    5660        uint8_t efi_signature[8];
     
    7781        service_id_t device;
    7882        /** Linked list of partitions (initially NULL) */
    79         //g_part_t * partitions;        //shall we keep this? same problem as in libmbr
    80         //NOTE: if we have partition list here, do we free() it or not?
    8183} gpt_t;
    8284
     
    109111        /** Resizable partition array */
    110112        gpt_entry_t * part_array;
    111        
    112113} gpt_parts_t;
    113114
     
    115116        const char * desc;
    116117        const char * guid;
    117 }
     118};
    118119
    119 struct partition_type gpt_ptypes[] {
     120struct partition_type gpt_ptypes[] = {
    120121        { "Unused entry",                                       "00000000-0000-0000-0000-000000000000" },
    121122        { "MBR partition scheme",                       "024DEE41-33E7-11D3-9D69-0008C781F39F" },
     
    184185
    185186extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle);
    186 extern int gpt_write_gpt_header(gpt_header_t header, service_id_t dev_handle);
     187extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
    187188
    188189extern gpt_parts_t * gpt_read_partitions(gpt_t * gpt);
    189 extern int gpt_write_partitions(gpt_parts_t * parts, gpt_t * header);
    190 extern gpt_parts_t * gpt_add_partition(gpt_parts_t * parts, g_part_t partition);
    191 extern gpt_parts_t * gpt_remove_partition(gpt_parts_t * parts, int idx);
     190extern int                       gpt_write_partitions(gpt_parts_t * parts, gpt_t * header, service_id_t dev_handle);
     191extern int                       gpt_add_partition(gpt_parts_t * parts, g_part_t * partition);
     192extern void                      gpt_remove_partition(gpt_parts_t * parts, int idx);
     193extern void              gpt_set_part_type(g_part_t * p, int type);
     194extern void              gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length);
    192195
    193196extern void gpt_free_gpt(gpt_t * gpt);
Note: See TracChangeset for help on using the changeset viewer.