tech_log: May 2009

Wednesday, May 27, 2009

Transforming eth addr string to a sequence of numbers

Here is a function that takes a srting in a form 11:22:33:44:55:66,
or similar (for example 000001:022:3:000000000000000044:5:06) and transform it in a sequence of hex nubers to be stored in the appropriate nvram structure field, which is of type char eth_address[6] (so it really takes number, not string chars and ':' delimiters) :

int i = 0;
char *s = my_eth_addr_string;
char *e = NULL;
for (i = 0; i < 6; i++)
{
    nvram.eth_address[i] = s ? strtoul (s, &e, 16) : 0;
    if (s)
        s = (*e) ? e + 1 : e;
}

Friday, May 22, 2009

U-Boot environment vars

- In u-boot/include/configs/versatile.h :

/*-----------------------------------------------------------------------
 * FLASH and environment organization
 */

#define VERSATILE_SYS_BASE                    0x10000000
#define VERSATILE_SYS_FLASH_OFFSET            0x4C
#define VERSATILE_FLASHCTRL              (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
#define VERSATILE_FLASHPROG_FLVPPEN          (1 << 0)    /* Enable writing to flash */

#define CFG_MAX_FLASH_BANKS    1        /* max number of memory banks */
#define PHYS_FLASH_SIZE         0x34000000    /* 64MB */
/* timeout values are in ticks */
#define CFG_FLASH_ERASE_TOUT    (20*CFG_HZ)    /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT    (20*CFG_HZ)    /* Timeout for Flash Write */
#define CFG_MAX_FLASH_SECT    (256)

#define PHYS_FLASH_1        (CFG_FLASH_BASE)

#define CFG_ENV_IS_IN_FLASH     1               /* env in flash instead of CFG_ENV_IS_NOWHERE */
#define CFG_ENV_SECT_SIZE       0x00020000      /* 256 KB sectors (x2) */
#define CFG_ENV_SIZE            0x10000         /* Total Size of Environment Sector */
#define CFG_ENV_OFFSET          0x01f00000      /* environment starts here  */
#define CFG_ENV_ADDR            (CFG_FLASH_BASE + CFG_ENV_OFFSET)


This is important - CFG_ENV_ADDR. It tells where will be env variables held in memory (in this case flash).


- In u-boot/common/env_flash.c :

char * env_name_spec = "Flash";

#ifdef ENV_IS_EMBEDDED

extern uchar environment[];
env_t *env_ptr = (env_t *)(&environment[0]);

#ifdef CMD_SAVEENV
/* static env_t *flash_addr = (env_t *)(&environment[0]);-broken on ARM-wd-*/
static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
#endif

#else /* ! ENV_IS_EMBEDDED */

env_t *env_ptr = (env_t *)CFG_ENV_ADDR;
#ifdef CMD_SAVEENV
static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
#endif

#endif /* ENV_IS_EMBEDDED */

#ifdef CFG_ENV_ADDR_REDUND
static env_t *flash_addr_new = (env_t *)CFG_ENV_ADDR_REDUND;

/* CFG_ENV_ADDR is supposed to be on sector boundary */
static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1;
static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1;

#define ACTIVE_FLAG   1
#define OBSOLETE_FLAG 0
#endif /* CFG_ENV_ADDR_REDUND */

extern uchar default_environment[];
extern int default_environment_size;

Also there basic intialization of gd general data structure (and to check if Flash is OK, stuff like this...) :

int  env_init(void)
{
#ifdef CONFIG_OMAP2420H4
    int flash_probe(void);

    if(flash_probe() == 0)
        goto bad_flash;
#endif
    if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
        gd->env_addr  = (ulong)&(env_ptr->data);
        gd->env_valid = 1;
        return(0);
    }
#ifdef CONFIG_OMAP2420H4
bad_flash:
#endif
    gd->env_addr  = (ulong)&default_environment[0];
    gd->env_valid = 0;
    return (0);
}

- In u-boot/arm_lib/board.c :

gd pointer to env is initialized:

typedef int (init_fnc_t) (void);

int print_cpuinfo (void); /* test-only */

init_fnc_t *init_sequence[] = {
    cpu_init,        /* basic cpu dependent setup */
    board_init,        /* basic board dependent setup */
    interrupt_init,        /* set up exceptions */
    env_init,        /* initialize environment */
    init_baudrate,        /* initialze baudrate settings */
    serial_init,        /* serial communications setup */
    console_init_f,        /* stage 1 init of console */
    display_banner,        /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
    print_cpuinfo,        /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
    checkboard,        /* display board info */
#endif
    dram_init,        /* configure available RAM banks */
    display_dram_config,
    NULL,
};

void start_armboot (void)
{
    init_fnc_t **init_fnc_ptr;
    char *s;
#ifndef CFG_NO_FLASH
    ulong size;
#endif
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
    unsigned long addr;
#endif

    /* Pointer is writable since we allocated a register for it */
    gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
    /* compiler optimization barrier needed for GCC >= 3.4 */
    __asm__ __volatile__("": : :"memory");

    memset ((void*)gd, 0, sizeof (gd_t));
    gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
    memset (gd->bd, 0, sizeof (bd_t));

    monitor_flash_len = _bss_start - _armboot_start;

    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
        if ((*init_fnc_ptr)() != 0) {
            hang ();
        }
    }

which is a call to function in u-boot/common/env_flash.c.


Chunk of memory in Flash that hoslds env variables is later relocated from Flash to RAM :

/* initialize environment */
    env_relocate ();



Tuesday, May 19, 2009

Some missing includes

problem : test.c:392: warning: incompatible implicit declaration of built-in function ‘memcpy’
solution : #include <string.h>

problem : linux/example.h:29: error: expected specifier-qualifier-list before ‘uint32_t’
solution : #include <inttypes.h>

Also note : for using strerr() and friends include errno.h


Friday, May 15, 2009

Linux relocation address - where to find it

Here is a liitle text that help you find zreladdr-y needed by the U-Boot bootloader procedure to copy Linux kernel to SDRAM and launch it:<br />
As you could have notice from the mach-types file, the name of the variable is not MACH_CM922TXA10,
but CONFIG_ is appended by the configuration tool, and this variable contains either a ’n’ or an
’y’ (for no or yes boolean value). If it is selected (yes value), the name of the folder of our machine is
appended to the machine-y variable, which contains the folders to be visited during compilation (machis
automatically appended). make will enter in our folder, but we must tell him what it must do, then we
create the arch/arm/mach-cm922txa10/Makefile with the content :
#
# Makefile for the linux kernel.
#
# Object file lists.
obj-y := arch.o irq.o mm.o time.o
obj-m :=
obj-n :=
obj- :=
This Makefile is quite static since we have no configuration available at this time. Object files
listed here are inherited from the EPXA10db machine support. In the same folder we have to put an extra
Makefile, the Makefile.boot which only contains the physical address of the text segment (this
gives the value of ZRELADDR, which is the physical address of TEXTADDR) :
zreladdr-y := 0x00008000

------------------------------------

example:

drasko@marx:~/linux-2.6/arch/arm/mach-versatile$ cat Makefile.boot
       zreladdr-y    := 0x00008000
params_phys-y    := 0x00000100
   initrd_phys-y    := 0x00800000







Where is that god damn MD5 lib?

Trying to link your code that uses MD5_Init(&ctx), MD5_Update() and MD5_Final(md5_sum, &ctx), but you just can not find the library that provides the function on Linux? <br />
Well - it is lib openssl, http://www.openssl.org/.

Iclude header:  #include <openssl/md5.h>
Link your code with:  -lssl.






strtoul() and friends in U-Boot

Cannot find them? Look at the u-boot/lib_generic/vsprintf.c.
There is definition for:
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
and the others..


Monday, May 4, 2009

Adding a command to u-boot

1) Add .o file to COBJS in ./common/Makefile
2) Add CFG_CMD_<MY_COMMAND> to CONFIG_COMMANDS macro in ./include/configs/<board_name>.h
3) Add CFG_CMD_<MY_COMMAND> definition to ./include/cmd_confdefs.h