Changeset 8f6c7785 in mainline


Ignore:
Timestamp:
2013-04-26T02:55:32Z (11 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
700f89e
Parents:
d617050
Message:

logical write functional

Files:
8 edited

Legend:

Unmodified
Added
Removed
  • tools/toolchain.sh

    rd617050 r8f6c7785  
    5656BINUTILS_RELEASE=""
    5757#GCC_VERSION="4.7.2"
    58 GCC_VERSION="4.8.0"
     58GCC_VERSION="4.7.3"
     59#GCC_VERSION="4.8.0"
    5960GDB_VERSION="7.5"
    6061
     
    7273        HEADER="$2"
    7374        BODY="$3"
    74        
     75
    7576        FNAME="/tmp/conftest-$$"
    76        
     77
    7778        echo "#include ${HEADER}" > "${FNAME}.c"
    7879        echo >> "${FNAME}.c"
     
    8283        echo "  return 0;" >> "${FNAME}.c"
    8384        echo "}" >> "${FNAME}.c"
    84        
     85
    8586        cc -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
    8687        RC="$?"
    87        
     88
    8889        if [ "$RC" -ne "0" ] ; then
    8990                echo " ${DEPENDENCY} not found, too old or compiler error."
     
    114115                echo
    115116                echo "Script failed: $2"
    116                
     117
    117118                exit 1
    118119        fi
     
    122123        FILE="$1"
    123124        SUM="$2"
    124        
     125
    125126        COMPUTED="`md5sum "${FILE}" | cut -d' ' -f1`"
    126127        if [ "${SUM}" != "${COMPUTED}" ] ; then
    127128                echo
    128129                echo "Checksum of ${FILE} does not match."
    129                
     130
    130131                exit 2
    131132        fi
     
    157158        echo "defined, /usr/local/cross will be used by default."
    158159        echo
    159        
     160
    160161        exit 3
    161162}
     
    167168show_countdown() {
    168169        TM="$1"
    169        
     170
    170171        if [ "${TM}" -eq 0 ] ; then
    171172                echo
    172173                return 0
    173174        fi
    174        
     175
    175176        echo -n "${TM} "
    176177        change_title "${TM}"
    177178        sleep 1
    178        
     179
    179180        TM="`expr "${TM}" - 1`"
    180181        show_countdown "${TM}"
     
    212213        FILE="$2"
    213214        CHECKSUM="$3"
    214        
     215
    215216        if [ ! -f "${FILE}" ]; then
    216217                change_title "Downloading ${FILE}"
     
    218219                check_error $? "Error downloading ${FILE}."
    219220        fi
    220        
     221
    221222        check_md5 "${FILE}" "${CHECKSUM}"
    222223}
     
    224225source_check() {
    225226        FILE="$1"
    226        
     227
    227228        if [ ! -f "${FILE}" ]; then
    228229                echo
    229230                echo "File ${FILE} not found."
    230                
     231
    231232                exit 4
    232233        fi
     
    235236cleanup_dir() {
    236237        DIR="$1"
    237        
     238
    238239        if [ -d "${DIR}" ]; then
    239240                change_title "Removing ${DIR}"
     
    246247        DIR="$1"
    247248        DESC="$2"
    248        
     249
    249250        change_title "Creating ${DESC}"
    250251        echo ">>> Creating ${DESC}"
    251        
     252
    252253        mkdir -p "${DIR}"
    253254        test -d "${DIR}"
     
    258259        FILE="$1"
    259260        DESC="$2"
    260        
     261
    261262        change_title "Unpacking ${DESC}"
    262263        echo " >>> Unpacking ${DESC}"
    263        
     264
    264265        tar -xjf "${FILE}"
    265266        check_error $? "Error unpacking ${DESC}."
     
    270271        check_dependecies
    271272        show_countdown 10
    272        
     273
    273274        BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
    274275        GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
    275276        GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
    276        
     277
    277278        download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "ee0f10756c84979622b992a4a61ea3f5"
    278279        download_fetch "${GCC_SOURCE}" "${GCC}" "cc308a0891e778cfda7a151ab8a6e762"
     
    283284        PLATFORM="$1"
    284285        TARGET="$2"
    285        
     286
    286287        WORKDIR="${BASEDIR}/${PLATFORM}"
    287288        BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
     
    289290        OBJDIR="${WORKDIR}/gcc-obj"
    290291        GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
    291        
     292
    292293        if [ -z "${CROSS_PREFIX}" ] ; then
    293294                CROSS_PREFIX="/usr/local/cross"
    294295        fi
    295        
     296
    296297        PREFIX="${CROSS_PREFIX}/${PLATFORM}"
    297        
     298
    298299        echo ">>> Downloading tarballs"
    299300        #source_check "${BASEDIR}/${BINUTILS}"
    300301        source_check "${BASEDIR}/${GCC}"
    301302        #source_check "${BASEDIR}/${GDB}"
    302        
     303
    303304        echo ">>> Removing previous content"
    304305        #cleanup_dir "${PREFIX}"
    305306        #cleanup_dir "${WORKDIR}"
    306        
     307
    307308        create_dir "${PREFIX}" "destination directory"
    308309        create_dir "${OBJDIR}" "GCC object directory"
    309        
     310
    310311        echo ">>> Unpacking tarballs"
    311312        cd "${WORKDIR}"
    312313        check_error $? "Change directory failed."
    313        
    314         unpack_tarball "${BASEDIR}/${BINUTILS}" "binutils"
    315         #unpack_tarball "${BASEDIR}/${GCC}" "GCC"
    316         unpack_tarball "${BASEDIR}/${GDB}" "GDB"
    317        
    318         echo ">>> Processing binutils (${PLATFORM})"
    319         cd "${BINUTILSDIR}"
     314
     315        #unpack_tarball "${BASEDIR}/${BINUTILS}" "binutils"
     316        unpack_tarball "${BASEDIR}/${GCC}" "GCC"
     317        #unpack_tarball "${BASEDIR}/${GDB}" "GDB"
     318
     319        #echo ">>> Processing binutils (${PLATFORM})"
     320        #cd "${BINUTILSDIR}"
     321        #check_error $? "Change directory failed."
     322
     323        #change_title "binutils: configure (${PLATFORM})"
     324        #CFLAGS=-Wno-error ./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --disable-nls --disable-werror
     325        #check_error $? "Error configuring binutils."
     326
     327        #change_title "binutils: make (${PLATFORM})"
     328        #make all install
     329        #check_error $? "Error compiling/installing binutils."
     330
     331        echo ">>> Processing GCC (${PLATFORM})"
     332        cd "${OBJDIR}"
    320333        check_error $? "Change directory failed."
    321        
    322         change_title "binutils: configure (${PLATFORM})"
    323         CFLAGS=-Wno-error ./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --disable-nls --disable-werror
    324         check_error $? "Error configuring binutils."
    325        
    326         change_title "binutils: make (${PLATFORM})"
    327         make all install
    328         check_error $? "Error compiling/installing binutils."
    329        
    330         echo ">>> Processing GCC (${PLATFORM})"
    331         #cd "${OBJDIR}"
     334
     335        change_title "GCC: configure (${PLATFORM})"
     336        "${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared --enable-lto --disable-werror
     337        check_error $? "Error configuring GCC."
     338
     339        change_title "GCC: make (${PLATFORM})"
     340        PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
     341        check_error $? "Error compiling/installing GCC."
     342
     343        #echo ">>> Processing GDB (${PLATFORM})"
     344        #cd "${GDBDIR}"
    332345        #check_error $? "Change directory failed."
    333        
    334         change_title "GCC: configure (${PLATFORM})"
    335         #"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared --enable-lto --disable-werror
    336         #check_error $? "Error configuring GCC."
    337        
    338         change_title "GCC: make (${PLATFORM})"
    339         #PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
    340         #check_error $? "Error compiling/installing GCC."
    341        
    342         echo ">>> Processing GDB (${PLATFORM})"
    343         cd "${GDBDIR}"
    344         check_error $? "Change directory failed."
    345        
    346         change_title "GDB: configure (${PLATFORM})"
    347         ./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-"
    348         check_error $? "Error configuring GDB."
    349        
    350         change_title "GDB: make (${PLATFORM})"
    351         make all install
    352         check_error $? "Error compiling/installing GDB."
    353        
     346
     347        #change_title "GDB: configure (${PLATFORM})"
     348        #./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-"
     349        #check_error $? "Error configuring GDB."
     350
     351        #change_title "GDB: make (${PLATFORM})"
     352        #make all install
     353        #check_error $? "Error compiling/installing GDB."
     354
    354355        cd "${BASEDIR}"
    355356        check_error $? "Change directory failed."
    356        
     357
    357358        echo ">>> Cleaning up"
    358359        cleanup_dir "${WORKDIR}"
    359        
     360
    360361        echo
    361362        echo ">>> Cross-compiler for ${TARGET} installed."
     
    439440                build_target "arm32" "arm-linux-gnueabi" &
    440441                wait
    441                
     442
    442443                build_target "ia32" "i686-pc-linux-gnu" &
    443444                build_target "ia64" "ia64-pc-linux-gnu" &
    444445                wait
    445                
     446
    446447                build_target "mips32" "mipsel-linux-gnu" &
    447448                build_target "mips32eb" "mips-linux-gnu" &
    448449                wait
    449                
     450
    450451                build_target "mips64" "mips64el-linux-gnu" &
    451452                build_target "ppc32" "ppc-linux-gnu" &
    452453                wait
    453                
     454
    454455                build_target "ppc64" "ppc64-linux-gnu" &
    455456                build_target "sparc64" "sparc64-linux-gnu" &
  • uspace/app/hdisk/func_gpt.c

    rd617050 r8f6c7785  
    4949                return ENOMEM;
    5050        }
    51        
     51
    5252        return set_gpt_partition(in, p);
    5353}
     
    5959        printf("Number of the partition to delete (counted from 0): ");
    6060        idx = get_input_size_t(in);
    61        
     61
    6262        if (gpt_remove_partition(data->gpt.parts, idx) == -1) {
    6363                printf("Warning: running low on memory, not resizing...\n");
    6464        }
    65        
     65
    6666        return EOK;
    6767}
     
    6969int print_gpt_parts(union table_data * data)
    7070{
     71        //int rc;
    7172        printf("Current partition scheme (GPT):\n");
    7273        printf("\t\tStart:\tEnd:\tLength:\tType:\tName:\n");
    7374       
    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));
     75        size_t i = 0;
     76       
     77        gpt_part_foreach(data->gpt.parts, iter) {
     78                //printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length,
     79                //              iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter));
     80                printf("%3u\t%10llu %10llu %10llu %3d %s\n", i, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
     81                                gpt_get_end_lba(iter) - gpt_get_start_lba(iter), gpt_get_part_type(iter),
     82                                gpt_get_part_name(iter));
     83                i++;
    7784        }
    78        
    79         return rc;
     85
     86        //return rc;
     87        return EOK;
    8088}
    8189
     
    8391{
    8492        int rc;
    85        
     93
    8694        rc = gpt_write_partitions(data->gpt.parts, data->gpt.gpt, dev_handle);
    8795        if (rc != EOK) {
     
    8997                return rc;
    9098        }
    91        
     99
    92100        rc = gpt_write_gpt_header(data->gpt.gpt, dev_handle);
    93101        if (rc != EOK) {
     
    95103                return rc;
    96104        }
    97        
     105
    98106        return EOK;
    99107}
     
    106114static int set_gpt_partition(tinput_t * in, gpt_part_t * p)
    107115{
    108         int rc;
    109        
     116        //int rc;
     117
    110118        uint64_t sa, ea;
    111        
     119
    112120        printf("Set starting address (number): ");
    113121        sa = get_input_uint64(in);
     
    115123        printf("Set end addres (number): ");
    116124        ea = get_input_uint64(in);
    117        
     125
    118126        if (ea <= sa) {
    119127                printf("Invalid value.\n");
    120128                return EINVAL;
    121129        }
    122        
    123        
    124         p->start_addr = sa;
    125         p->length = ea - sa;
    126        
     130
     131
     132        //p->start_addr = sa;
     133        gpt_set_start_lba(p, sa);
     134        //p->length = ea - sa;
     135        gpt_set_end_lba(p, ea);
     136
    127137        return EOK;
    128138}
  • uspace/app/hdisk/func_mbr.c

    rd617050 r8f6c7785  
    8383
    8484        printf("Current partition scheme:\n");
    85         printf("\t\tBootable:\tStart:\tEnd:\tLength:\tType:\n");
    86 
     85        //printf("\t\tBootable:\tStart:\tEnd:\tLength:\tType:\n");
     86        printf("\t\t%10s  %10s %10s %10s %7s\n", "Bootable:", "Start:", "End:", "Length:", "Type:");
     87       
     88        mbr_part_t * it;
    8789        mbr_part_foreach(data->mbr.parts, it) {
    8890                if (it->type == PT_UNUSED)
    8991                        continue;
    9092
    91                 printf("\t P%d:\t", num);
     93                printf("\tP%d:\t", num);
    9294                if (mbr_get_flag(it, ST_BOOT))
    9395                        printf("*");
     
    9597                        printf(" ");
    9698
    97                 printf("\t%10u %10u %10u %3d\n", it->start_addr, it->start_addr + it->length, it->length, it->type);
     99                printf("\t%10u %10u %10u %7x\n", it->start_addr, it->start_addr + it->length, it->length, it->type);
    98100
    99101                ++num;
     
    101103
    102104        printf("%d partitions found.\n", num);
     105        printf("DEBUG: primary: %hhu, logical: %u\n", data->mbr.parts->n_primary, data->mbr.parts->n_logical);
    103106       
    104107        return EOK;
  • uspace/app/hdisk/hdisk.c

    rd617050 r8f6c7785  
    7373                return -1;
    7474        }
    75        
     75
    7676        init_table();
    77        
     77
    7878        mbr_t * mbr = mbr_read_mbr(dev_handle);
    7979        if(mbr == NULL) {
     
    9898                mbr_free_mbr(mbr);
    9999                gpt_t * gpt = gpt_read_gpt_header(dev_handle);
     100                printf("here3\n");
    100101                if(gpt == NULL) {
    101102                        printf("Failed to read and parse GPT header. Exiting.\n");
     
    103104                }
    104105                set_table_gpt(gpt);
     106                printf("here4\n");
    105107                gpt_partitions_t * parts = gpt_read_partitions(gpt);
     108                printf("here5\n");
    106109                if(parts == NULL) {
    107110                        printf("Failed to read and parse partitions.\n" \
     
    114117
    115118        rc = interact(dev_handle);
    116 
     119       
    117120        free_table();
    118 
     121       
    119122        return rc;
    120123}
     
    188191                input = getchar();
    189192                printf("%c\n", input);
    190                
     193
    191194
    192195                //rc = tinput_read(in, &str);
  • uspace/lib/gpt/libgpt.c

    rd617050 r8f6c7785  
    6767        int rc;
    6868        size_t b_size;
    69 
     69       
     70        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
     71        if (rc != EOK)
     72                return NULL;
     73       
    7074        rc = block_get_bsize(dev_handle, &b_size);
    7175        if (rc != EOK) {
     
    7377                return NULL;
    7478        }
    75 
     79       
    7680        gpt_t * gpt = malloc(sizeof(gpt_t));
    7781        if (gpt == NULL) {
     
    8084        }
    8185
    82         gpt->raw_data = malloc(b_size);// We might need only sizeof(gpt_header_t),
     86        gpt->raw_data = malloc(b_size); // We might need only sizeof(gpt_header_t),
    8387        if (gpt == NULL) {                              // but we should follow specs and have
    8488                free(gpt);                                      // zeroes through all the rest of the block
     
    8690                return NULL;
    8791        }
    88 
    89 
     92       
     93       
    9094        rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, gpt->raw_data);
    9195        if (rc == EBADCHECKSUM || rc == EINVAL) {
     
    103107                }
    104108        }
    105 
     109       
    106110        gpt->device = dev_handle;
    107 
     111        block_fini(dev_handle);
    108112        return gpt;
    109 
     113       
    110114fail:
     115        block_fini(dev_handle);
    111116        gpt_free_gpt(gpt);
    112117        return NULL;
     
    130135                                        uint32_t_le2host(gpt->raw_data->header_size));
    131136
     137        rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
     138        if (rc != EOK)
     139                return rc;
     140
    132141        rc = block_get_bsize(dev_handle, &b_size);
    133         if (rc != EOK)
    134                 return rc;
    135 
    136         rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
    137142        if (rc != EOK)
    138143                return rc;
     
    252257        gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->fill * gpt->raw_data->entry_size);
    253258
     259        rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
     260        if (rc != EOK)
     261                return rc;
     262
    254263        rc = block_get_bsize(dev_handle, &b_size);
    255         if (rc != EOK)
    256                 return rc;
    257 
    258         rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
    259264        if (rc != EOK)
    260265                return rc;
     
    473478        int rc;
    474479
    475         rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
    476         if (rc != EOK)
    477                 return rc;
    478 
    479480        rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
    480         block_fini(dev_handle);
    481         if (rc != EOK)
    482                 return rc;
    483 
     481        if (rc != EOK)
     482                return rc;
    484483
    485484        unsigned int i;
  • uspace/lib/gpt/libgpt.h

    rd617050 r8f6c7785  
    153153extern void                                     gpt_set_start_lba       (gpt_part_t * p, uint64_t start);
    154154extern uint64_t                         gpt_get_start_lba       (gpt_part_t * p);
    155 extern void                                     gpt_set_end_lba         (gpt_part_t * p, uint64_t start);
     155extern void                                     gpt_set_end_lba         (gpt_part_t * p, uint64_t end);
    156156extern uint64_t                         gpt_get_end_lba         (gpt_part_t * p);
    157157extern unsigned char *          gpt_get_part_name       (gpt_part_t * p);
     
    162162
    163163
    164 #define gpt_foreach(parts, i, iterator) \
    165                 for(size_t i = 0, gpt_part_t * iterator = parts->part_array; \
    166                     i < parts->fill; i++, iterator++)
     164#define gpt_part_foreach(parts, iterator) \
     165                for(gpt_part_t * iterator = (parts)->part_array; \
     166                    iterator < (parts)->part_array + (parts)->fill; ++iterator)
    167167
    168168extern void gpt_free_gpt(gpt_t * gpt);
  • uspace/lib/mbr/libmbr.c

    rd617050 r8f6c7785  
    3333 */
    3434
     35#include <async.h>
     36#include <assert.h>
     37#include <block.h>
     38#include <byteorder.h>
     39#include <errno.h>
    3540#include <ipc/bd.h>
    36 #include <async.h>
     41#include <mem.h>
    3742#include <stdio.h>
    38 #include <block.h>
    39 #include <errno.h>
    4043#include <stdlib.h>
    41 #include <assert.h>
    42 #include <byteorder.h>
    4344
    4445#include "libmbr.h"
     
    4748static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base);
    4849static int decode_logical(mbr_t * mbr, mbr_partitions_t * p, mbr_part_t * ext);
    49 static void encode_part(mbr_part_t * src, pt_entry_t * trgt, uint32_t base);
     50static void encode_part(mbr_part_t * src, pt_entry_t * trgt, uint32_t base, bool ebr);
    5051static int check_overlap(mbr_part_t * p1, mbr_part_t * p2);
    5152static int check_encaps(mbr_part_t * inner, mbr_part_t * outer);
    5253static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee);
     54
     55static void debug_print(unsigned char * data, size_t bytes);
    5356
    5457/** Read MBR from specific device
     
    128131mbr_partitions_t * mbr_read_partitions(mbr_t * mbr)
    129132{
    130         int rc, i;
     133        int rc, i, rc_ext;
    131134        mbr_part_t * p;
    132135        mbr_part_t * ext = NULL;
    133136        mbr_partitions_t * parts;
    134 
     137       
    135138        if (mbr == NULL)
    136139                return NULL;
    137 
     140       
    138141        parts = mbr_alloc_partitions();
    139142        if (parts == NULL) {
     
    145148                if (mbr->raw_data.pte[i].ptype == PT_UNUSED)
    146149                        continue;
    147 
    148                 p = malloc(sizeof(mbr_part_t));
     150               
     151                //p = malloc(sizeof(mbr_part_t));
     152                p = mbr_alloc_partition();
    149153                if (p == NULL) {
    150154                        printf(LIBMBR_NAME ": Error on memory allocation.\n");
    151                         free(p);
    152155                        mbr_free_partitions(parts);
    153156                        return NULL;
    154157                }
    155158                //list_append(&(p->link), &(parts->list));
    156                 p->ebr = NULL;
    157                 if (decode_part(&(mbr->raw_data.pte[i]), p, 0)) {
     159                rc_ext = decode_part(&(mbr->raw_data.pte[i]), p, 0);
     160                mbr_set_flag(p, ST_LOGIC, false);
     161                rc = mbr_add_partition(parts, p);
     162                if (rc != ERR_OK) {
     163                        printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
     164                                   LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
     165                        return NULL;
     166                }
     167               
     168                if (rc_ext) {
    158169                        ext = p;
    159170                        parts->l_extended = list_last(&(parts->list));
    160171                }
    161                 mbr_set_flag(p, ST_LOGIC, false);
    162                 mbr_add_partition(parts, p);
    163         }
    164 
     172        }
     173       
    165174        // Fill in the primary partitions and generate logical ones, if any
    166175        rc = decode_logical(mbr, parts, ext);
     
    169178                           LIBMBR_NAME ": Partition list may be incomplete.\n");
    170179        }
    171 
     180       
     181        //DEBUG:
     182        //debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512);
    172183        return parts;
    173184}
     
    188199        mbr_part_t * ext = (parts->l_extended == NULL) ? NULL
    189200                                        : list_get_instance(parts->l_extended, mbr_part_t, link);
    190 
     201       
    191202        //br_block_t * last_ebr = NULL;
    192203        //link_t * it;
    193 
     204       
    194205        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);
    195 
     206       
    196207        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    197208        if (rc != EOK) {
     
    228239
    229240        }*/
    230 
     241       
    231242        link_t * l = parts->list.head.next;
    232 
     243       
    233244        // Encoding primary partitions
    234245        for (i = 0; i < parts->n_primary; i++) {
    235246                p = list_get_instance(l, mbr_part_t, link);
    236                 encode_part(p, &(mbr->raw_data.pte[i]), 0);
     247                encode_part(p, &(mbr->raw_data.pte[i]), 0, false);
    237248                l = l->next;
    238249        }
    239 
     250       
    240251        // Writing MBR
    241252        rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
     
    244255                goto end;
    245256        }
    246 
     257       
    247258        if (ext == NULL)
    248259                goto no_extended;
    249 
    250 
     260       
     261        //DEBUG:
     262        //debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512);
    251263        uint32_t base = ext->start_addr;
    252         uint32_t addr = base;
    253 
     264        //uint32_t addr = base;
     265        //uint32_t prev_addr;
     266        //mbr_part_t * tmp;
     267        mbr_part_t * prev_p;
    254268        // Encoding and writing first logical partition
    255269        if (l != &(parts->list.head)) {
    256270                p = list_get_instance(l, mbr_part_t, link);
    257                 if (p->ebr == NULL) {
    258                         p->ebr = alloc_br();
    259                         if (p->ebr == NULL) {
    260                                 rc = ENOMEM;
    261                                 goto end;
    262                         }
    263                 }
    264 
    265                 encode_part(p, &(p->ebr->pte[0]), base);
    266 
    267                 if (l->next == &(parts->list.head))
    268                         encode_part(NULL, &(p->ebr->pte[1]), base);
    269                 else
    270                         encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base);
    271 
    272 
     271                p->ebr_addr = base;
     272                encode_part(p, &(p->ebr->pte[0]), base, false);
     273               
     274                /*if (l->next == &(parts->list.head))
     275                        encode_part(NULL, &(p->ebr->pte[1]), base, false);
     276                else {
     277                        tmp = list_get_instance(l->next, mbr_part_t, link);
     278                        //debug_print((unsigned char*) p->ebr, 512);
     279                        printf("DEBUG: base: %u, tmp: start: %u, end: %u\n", base, tmp->start_addr, tmp->start_addr + tmp->length);
     280                        //encode_part(tmp, &(p->ebr->pte[1]), base);
     281                        encode_part(tmp, &(p->ebr->pte[1]), base, true);
     282                        debug_print(((unsigned char*) p->ebr) + 446, 32);
     283                }
     284               
    273285                rc = block_write_direct(dev_handle, base, 1, p->ebr);
    274286                if (rc != EOK) {
    275287                        DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    276288                        goto end;
    277                 }
    278 
     289                }*/
     290               
    279291                l = l->next;
    280         }
    281 
    282 
    283 
     292        } else
     293                goto no_logical;
     294       
     295        //prev_addr = base;
     296        prev_p = p;
     297       
    284298        // Encoding and writing logical partitions
    285299        while (l != &(parts->list.head)) {
    286300                p = list_get_instance(l, mbr_part_t, link);
    287                 if (p->ebr == NULL) {
    288                         p->ebr = alloc_br();
    289                         if (p->ebr == NULL) {
    290                                 rc = ENOMEM;
    291                                 goto end;
    292                         }
    293                 }
    294 
    295                 addr = p->start_addr - base;
    296                 encode_part(p, &(p->ebr->pte[0]), addr);
    297 
    298                 if (l->next == &(parts->list.head))
    299                         encode_part(NULL, &(p->ebr->pte[1]), base);
     301               
     302                /* Checking whether EBR address makes sense. If not, we take a guess.
     303                 * So far this is simple, we just take the first preceeding sector.
     304                 * Fdisk always reserves at least 2048 sectors (1MiB), so it can have
     305                 * the EBR aligned as well as the partition itself. Parted reserves
     306                 * minimum one sector, like we do.
     307                 *
     308                 * Note that we know there is at least one sector free from previous checks.
     309                 * Also note that the user can set ebr_addr to their liking (if it's valid). */         
     310                if (p->ebr_addr >= p->start_addr || p->ebr_addr <= (prev_p->start_addr + prev_p->length)) {
     311                        p->ebr_addr = p->start_addr - 1;
     312                        DEBUG_PRINT_0(LIBMBR_NAME ": Warning: invalid EBR address.\n");
     313                }
     314               
     315                encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false);
     316                debug_print(((unsigned char*) p->ebr) + 446, 32);
     317                encode_part(p, &(prev_p->ebr->pte[1]), base, true);
     318                debug_print(((unsigned char*) prev_p->ebr) + 446, 32);
     319                /*if (l->next == &(parts->list.head))
     320                        encode_part(NULL, &(p->ebr->pte[1]), base, false);
    300321                else
    301                         encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base);
    302 
    303 
    304                 rc = block_write_direct(dev_handle, addr, 1, p->ebr);
     322                        encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base, true);
     323                */
     324               
     325                rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
    305326                if (rc != EOK) {
    306327                        DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    307328                        goto end;
    308329                }
    309 
     330               
     331                prev_p = p;
    310332                l = l->next;
    311333        }
    312 
     334       
     335        encode_part(NULL, &(prev_p->ebr->pte[1]), 0, false);
     336        rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
     337        if (rc != EOK) {
     338                DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
     339                goto end;
     340        }
     341       
     342no_logical:
    313343no_extended:
    314 
     344       
    315345        /*if (ext == NULL)
    316346                goto no_extended;
     
    514544                p = p->next;
    515545        }*/
    516 
     546       
    517547        rc = EOK;
    518 
     548       
    519549end:
    520550        block_fini(dev_handle);
    521 
     551       
    522552        return rc;
    523553}
     
    536566        p->start_addr = 0;
    537567        p->length = 0;
     568        p->ebr_addr = 0;
    538569
    539570        return p;
     
    561592int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
    562593{
    563         if (mbr_get_flag(p, ST_LOGIC)) {
    564                 // adding logical part
     594        if (mbr_get_flag(p, ST_LOGIC)) { // adding logical part
    565595                if (parts->l_extended == NULL) {
    566596                        return ERR_NO_EXTENDED;
    567597                }
    568                 if (!check_encaps(p, list_get_instance(parts->l_extended, mbr_part_t, link))) {
     598                mbr_part_t * ext = list_get_instance(parts->l_extended, mbr_part_t, link);
     599                if (!check_encaps(p, ext)) {
     600                        //printf("DEBUG: OOB: start: %u, end: %u\n", h->start_addr, h->start_addr + h->length);
     601                        //printf("DEBUG: OOB: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length);
    569602                        return ERR_OUT_BOUNDS;
    570603                }
    571604
    572605                mbr_part_t * last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
     606                mbr_part_t * iter;
     607                uint32_t ebr_space = 1;
    573608                mbr_part_foreach(parts, iter) {
    574609                        if (mbr_get_flag(iter, ST_LOGIC)) {
    575610                                if (check_overlap(p, iter)) {
     611                                        //printf("DEBUG: overlap: start: %u, end: %u\n", iter->start_addr, iter->start_addr + iter->length);
     612                                        //printf("DEBUG: overlap: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length);
    576613                                        return ERR_OVERLAP;
    577614                                }
    578                                 if (check_preceeds(p, iter)) {
     615                                if (check_preceeds(iter, p)) {
    579616                                        last = iter;
     617                                        ebr_space = p->start_addr - (last->start_addr + last->length);
     618                                } else
    580619                                        break;
    581                                 }
    582620                        }
    583621                }
    584 
     622               
     623                // checking if there's at least one sector of space preceeding
     624               
     625                if (ebr_space < 1)
     626                        return ERR_NO_EBR;
     627               
     628                // checking if there's at least one sector of space following (for following partitions's EBR)
     629                if (last->link.next != &(parts->list.head)) {
     630                        if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1) {
     631                                return ERR_NO_EBR;
     632                        }
     633                }
     634               
     635                if (p->ebr == NULL) {
     636                        p->ebr = alloc_br();
     637                        if (p->ebr == NULL) {
     638                                return ERR_NOMEM;
     639                        }
     640                }
     641               
     642                //printf("DEBUG: last: start: %u\n", last->start_addr);
    585643                //list_prepend(&(p->link), &(parts->list));
    586                 list_insert_before(&(p->link), &(last->link));
     644                list_insert_after(&(p->link), &(last->link));
    587645                parts->n_logical += 1;
    588646        } else {
     
    591649                        return ERR_PRIMARY_FULL;
    592650                }
     651               
     652                // should we check if it's inside the drive's upper boundary?
     653                if (p->start_addr == 0) {
     654                        return ERR_OUT_BOUNDS;
     655                }
     656               
    593657                if (p->type == PT_EXTENDED && parts->l_extended != NULL) {
    594658                        return ERR_EXTENDED_PRESENT;
     
    598662                        list_append(&(p->link), &(parts->list));
    599663                } else {
     664                        mbr_part_t * iter;
    600665                        mbr_part_foreach(parts, iter) {
    601666                                if (mbr_get_flag(iter, ST_LOGIC)) {
    602667                                        list_insert_before(&(p->link), &(iter->link));
    603                                         parts->n_primary += 1;
    604668                                        break;
    605669                                } else if (check_overlap(p, iter)) {
     
    607671                                }
    608672                        }
    609                 }
     673                        if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link)) {
     674                                list_append(&(p->link), &(parts->list));
     675                        }
     676                       
     677                }
     678                parts->n_primary += 1;
    610679        }
    611680
     
    663732}
    664733
     734/** Get next aligned address (in sectors!) */
     735uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment)
     736{
     737        uint32_t div = addr / alignment;
     738        return (div + 1) * alignment;
     739}
     740
    665741/** Just a wrapper for free() */
    666742void mbr_free_mbr(mbr_t * mbr)
     
    691767        if (br == NULL)
    692768                return NULL;
    693 
     769       
     770        memset(br, 0, 512);
    694771        br->media_id = 0;
    695772        br->pad0 = 0;
    696773        br->signature = host2uint16_t_le(BR_SIGNATURE);
    697 
     774       
    698775        return br;
    699776}
     
    733810        uint32_t addr = base;
    734811        br_block_t * ebr;
    735 
     812       
    736813        rc = block_init(EXCHANGE_ATOMIC, mbr->device, 512);
    737814        if (rc != EOK)
    738815                return rc;
    739 
     816       
    740817        ebr = alloc_br();
    741818        if (ebr == NULL) {
     
    743820                goto end;
    744821        }
    745 
     822       
    746823        rc = block_read_direct(mbr->device, addr, 1, ebr);
    747824        if (rc != EOK) {
    748825                goto free_ebr_end;
    749826        }
    750 
     827       
    751828        if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
    752829                rc = EINVAL;
    753830                goto free_ebr_end;
    754831        }
    755 
     832       
    756833        if (ebr->pte[0].ptype == PT_UNUSED) {
    757834                rc = EOK;
    758835                goto free_ebr_end;
    759836        }
    760 
     837       
    761838        p = mbr_alloc_partition();
    762839        if (p == NULL) {
     
    764841                goto free_ebr_end;
    765842        }
    766 
    767 
     843       
    768844        decode_part(&(ebr->pte[0]), p, base);
    769845        mbr_set_flag(p, ST_LOGIC, true);
    770846        p->ebr = ebr;
    771         mbr_add_partition(parts, p);
    772 
     847        p->ebr_addr = addr;
     848        rc = mbr_add_partition(parts, p);
     849        if (rc != ERR_OK) {
     850                printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
     851                           LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
     852                return EINVAL;
     853        }
     854       
    773855        addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
    774 
     856        printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[1].first_lba);
     857       
    775858        while (ebr->pte[1].ptype != PT_UNUSED) {
    776859                ebr = alloc_br();
     
    779862                        goto end;
    780863                }
    781 
     864               
    782865                rc = block_read_direct(mbr->device, addr, 1, ebr);
    783866                if (rc != EOK) {
    784867                        goto free_ebr_end;
    785868                }
    786 
     869               
    787870                if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
    788871                        rc = EINVAL;
    789872                        goto free_ebr_end;
    790873                }
    791 
     874               
    792875                p = mbr_alloc_partition();
    793876                if (p == NULL) {
     
    795878                        goto free_ebr_end;
    796879                }
    797 
    798                 decode_part(&(ebr->pte[0]), p, base);
     880               
     881                //printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[0].first_lba);
     882                decode_part(&(ebr->pte[0]), p, addr);
    799883                mbr_set_flag(p, ST_LOGIC, true);
    800884                p->ebr = ebr;
    801                 mbr_add_partition(parts, p);
    802 
     885                p->ebr_addr = addr;
     886                rc = mbr_add_partition(parts, p);
     887                if (rc != ERR_OK) {
     888                        printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
     889                                   LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
     890                        return EINVAL;
     891                }
     892               
    803893                addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
    804894        }
    805 
     895       
    806896        rc = EOK;
    807 
     897        goto end;
     898       
    808899free_ebr_end:
    809900        free(ebr);
    810 
     901       
    811902end:
    812903        block_fini(mbr->device);
    813 
     904       
    814905        return rc;
    815906}
    816907
    817908/** Convert mbr_part_t to pt_entry_t */
    818 static void encode_part(mbr_part_t * src, pt_entry_t * trgt, uint32_t base)
     909static void encode_part(mbr_part_t * src, pt_entry_t * trgt, uint32_t base, bool ebr)
    819910{
    820911        if (src != NULL) {
    821912                trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE;
    822                 trgt->ptype = src->type;
    823                 trgt->first_lba = host2uint32_t_le(src->start_addr - base);
    824                 trgt->length = host2uint32_t_le(src->length);
     913                if (ebr) {      // encoding reference to EBR
     914                        trgt->ptype = PT_EXTENDED_LBA;
     915                        trgt->first_lba = host2uint32_t_le(src->ebr_addr - base);
     916                        trgt->length = host2uint32_t_le(src->length + src->start_addr - src->ebr_addr);
     917                } else {        // encoding reference to partition
     918                        trgt->ptype = src->type;
     919                        trgt->first_lba = host2uint32_t_le(src->start_addr - base);
     920                        trgt->length = host2uint32_t_le(src->length);
     921                }
    825922        } else {
    826923                trgt->status = 0;
     
    839936static int check_overlap(mbr_part_t * p1, mbr_part_t * p2)
    840937{
    841         if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length <= p2->start_addr) {
     938        if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length < p2->start_addr) {
    842939                return 0;
    843         } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length <= p1->start_addr) {
     940        } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length < p1->start_addr) {
    844941                return 0;
    845942        }
     
    864961}
    865962
    866 
    867 
     963static void debug_print(unsigned char * data, size_t bytes)
     964{
     965        size_t addr = 0;
     966        int i;
     967       
     968        while (bytes >= 16) {
     969                printf("%8x ", addr);
     970                for (i = 0; i < 8; i++) {
     971                        printf(" %2hhx", data[addr + i]);
     972                }
     973                printf(" ");
     974                for (i = 0; i < 8; i++) {
     975                        printf(" %2hhx", data[addr + i + 8]);
     976                }
     977                printf("\n");
     978               
     979                bytes -= 16;
     980                addr += 16;
     981        }
     982       
     983       
     984}
     985
     986
     987
  • uspace/lib/mbr/libmbr.h

    rd617050 r8f6c7785  
    8484        /** Extended partition */
    8585        PT_EXTENDED     = 0x05,
     86        /** Extended partition with LBA */
     87        PT_EXTENDED_LBA = 0x0F,
    8688        /** GPT Protective partition */
    8789        PT_GPT  = 0xEE,
     
    101103        /** Logical partition out of bounds */
    102104        ERR_OUT_BOUNDS,
     105        /** No space left for EBR */
     106        ERR_NO_EBR,
     107        /** Out of memory */
     108        ERR_NOMEM,
    103109} MBR_ERR_VAL;
    104110
     
    156162        /** Points to Extended Boot Record of logical partition */
    157163        br_block_t * ebr;
     164        /** EBR address */
     165        uint32_t ebr_addr;
    158166} mbr_part_t;
    159167
     
    194202extern int                      mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag);
    195203extern void                     mbr_set_flag(mbr_part_t * p, MBR_FLAGS flag, bool value);
     204extern uint32_t         mbr_get_next_aligned(uint32_t addr, unsigned int alignment);
    196205
    197206#define mbr_part_foreach(parts, iterator)       \
    198                         for (mbr_part_t * iterator = list_get_instance((parts)->list.head.next, mbr_part_t, link); \
    199                                 iterator != list_get_instance(&(parts)->list.head, mbr_part_t, link); \
    200                                 iterator = list_get_instance(iterator->link.next, mbr_part_t, link))
     207                        for (iterator = list_get_instance((parts)->list.head.next, mbr_part_t, link); \
     208                                 iterator != list_get_instance(&((parts)->list.head), mbr_part_t, link); \
     209                                 iterator = list_get_instance(iterator->link.next, mbr_part_t, link))
    201210
    202211
Note: See TracChangeset for help on using the changeset viewer.