示例#1
0
static int
dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
{

    if (dtrace_here) {
        printk("copycheck: uaddr=%p kaddr=%p size=%d\n", (void *) uaddr, (void*) kaddr, (int) size);
    }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
    if (__range_not_ok(uaddr, size)) {
#else
    if (!addr_valid(uaddr) || !addr_valid(uaddr + size)) {
#endif
//printk("uaddr=%p size=%d\n", uaddr, size);
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        cpu_core[cpu_get_id()].cpuc_dtrace_illval = uaddr;
        return (0);
    }
    return (1);
}
# endif

void
dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
              volatile uint16_t *flags)
{
    if (dtrace_memcpy_with_error((void *) kaddr, (void *) uaddr, size) == 0) {
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        return;
    }
}

void
dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
               volatile uint16_t *flags)
{
    if (dtrace_memcpy_with_error((void *) uaddr, (void *) kaddr, size) == 0) {
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        return;
    }
}

void
dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
                 volatile uint16_t *flags)
{
    if (dtrace_memcpy_with_error((void *) kaddr, (void *) uaddr, size) == 0) {
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        return;
    }
}

void
dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
                  volatile uint16_t *flags)
{
    if (dtrace_memcpy_with_error((void *) kaddr, (void *) uaddr, size) == 0) {
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        return;
    }
}

uint8_t
dtrace_fuword8(void *uaddr)
{
    extern uint8_t dtrace_fuword8_nocheck(void *);
    if (!access_ok(VERIFY_READ, uaddr, 1)) {
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        printk("dtrace_fuword8: uaddr=%p CPU_DTRACE_BADADDR\n", uaddr);
        cpu_core[cpu_get_id()].cpuc_dtrace_illval = (uintptr_t)uaddr;
        return (0);
    }
    return (dtrace_fuword8_nocheck(uaddr));
}

uint16_t
dtrace_fuword16(void *uaddr)
{
    extern uint16_t dtrace_fuword16_nocheck(void *);
    if (!access_ok(VERIFY_WRITE, uaddr, 2)) {
        printk("dtrace_fuword16: uaddr=%p CPU_DTRACE_BADADDR\n", uaddr);
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        cpu_core[cpu_get_id()].cpuc_dtrace_illval = (uintptr_t)uaddr;
        return (0);
    }
    return (dtrace_fuword16_nocheck(uaddr));
}

uint32_t
dtrace_fuword32(void *uaddr)
{
    extern uint32_t dtrace_fuword32_nocheck(void *);
    if (!addr_valid(uaddr)) {
        HERE2();
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        cpu_core[cpu_get_id()].cpuc_dtrace_illval = (uintptr_t)uaddr;
        return (0);
    }
    return (dtrace_fuword32_nocheck(uaddr));
}

uint64_t
dtrace_fuword64(void *uaddr)
{
    extern uint64_t dtrace_fuword64_nocheck(void *);
    if (!addr_valid(uaddr)) {
        HERE2();
        DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
        cpu_core[cpu_get_id()].cpuc_dtrace_illval = (uintptr_t)uaddr;
        return (0);
    }
    return (dtrace_fuword64_nocheck(uaddr));
}
示例#2
0
/* write fn to device */
int nrf_program_nrf24lu(devp dev, const char *fn){
    unsigned char cmd[2], data[64], *flash_copy, dirty_bv[64];
    FILE *fp = NULL;
    int ecode, block, page, rc;
    unsigned int first_addr, last_addr;
    IHexRecord record;

    printf("Programming nRF24LU\n");
    /* read the entire ROM into memory
     *
     * Why? Because Nordic doesn't have decent software. Their flash write
     * command erases the page first, instead of letting me decide if the page
     * should be erased first.
     *
     * Byte-level writing is offered by using a read-modify-write operation.
     * It would be smarter to operate on a per-page basis, but Intel HEX files
     * are not guaranteed to have sequential addressing. Since Nordic screwed
     * up and wild IHX files are adhoc, let's work with the whole 32k flash
     * memory at once.
     */
    if((flash_copy = malloc(FLASH_SIZE)) == NULL){
        ecode = -4;
        goto err;
    }
    printf("[*] Reading device.\n");
    for(block = 0; block < 0x200; block++){
        /* set address MSB */
        if((block % 0x100) == 0){
            cmd[0] = 0x06;
            cmd[1] = (unsigned char)(block / 256);
            if(nrf_cmd(dev, cmd, 2, data, 1)){
                ecode = -2;
                goto err;
            }
        }
        /* request the block */
        cmd[0] = 0x03;
        cmd[1] = (unsigned char)block;
        if(nrf_cmd(dev, cmd, 2, &flash_copy[block2addr(block)], 64)){
            ecode = -2;
            goto err;
        }
    }

    /* overwrite in-memory with IHX contents */
    if((fp = fopen(fn, "r")) == NULL){
        ecode = -1;
        goto err;
    }
    memset(dirty_bv, 0, sizeof(dirty_bv));
    while((rc = Read_IHexRecord(&record, fp)) == IHEX_OK &&
            record.type != IHEX_TYPE_01){
        if(record.type != IHEX_TYPE_00){
            /* we cannot process segment or linear ihex files */
            printf("[!] IHX file contains segment or linear addressing.\n");
            ecode = -5;
            goto err;
        }
        /* first and last byte that is touched by this record */
        first_addr = record.address;
        last_addr = record.address + record.dataLen - 1;
        if(!addr_valid(first_addr) || !addr_valid(last_addr)){
            printf("[!] IHX record touches invalid or protected bytes: "
                    "0x%04X - 0x%04X\n", first_addr, last_addr);
            ecode = -6;
            goto err;
        }
        /* only write if the ihx record changes memory */
        if(memcmp(&flash_copy[first_addr], record.data, record.dataLen)){
            /* copy record into memory */
            memcpy(&flash_copy[first_addr], record.data, record.dataLen);
            /* mark dirty blocks */
            for(block = addr2block(first_addr); block <= addr2block(last_addr);
                    block++){
                /* check the block since we might have some *really* long
                 * record
                 */
                if(!addr_valid(block2addr(block))){
                    printf("[!] IHX record touches invalid or protected bytes:"
                            " 0x%04X\n", block2addr(block));
                    ecode = -6;
                    goto err;
                }
                bitset(dirty_bv, block);
            }
        }
    }
    if(rc != IHEX_OK && rc != IHEX_ERROR_EOF){
        /* we had an error that isn't EOF */
        ecode = -4;
        goto err;
    }

    /* write to flash */
    printf("[*] Writing device");
    fflush(stdout);
    for(page = 0; page < 64; page++){
        /* Each page is 8 blocks, which conviently maps to our dirty bit vector
         * on byte boundries.
         */
        if(dirty_bv[page]){
            printf(".");
            fflush(stdout);
            if(nrf_write_page(dev, page, &flash_copy[page2addr(page)])){
                printf("\n[!] Write failed.\n");
                ecode = -7;
                goto err;
            }
        }
    }
    printf("\n");

    /* verify */
    printf("[*] Verifying device");
    fflush(stdout);
    for(block = 0; block < 512; block++){
        if(bitisset(dirty_bv, block)){
            if(nrf_compare_block(dev, block, &flash_copy[block2addr(block)])){
                printf("\n[!] Block %d failed.\n", block);
                ecode = -8;
                goto err;
            } else {
                printf(".");
                fflush(stdout);
            }
        }
    }
    printf("\n");

    ecode = 0;
err:
    if(flash_copy){
        free(flash_copy);
    }
    if(fp){
        fclose(fp);
    }
    return ecode;
}