On Thursday 29 July 2010 10:40:49 am Theo Debrouwere wrote:
> > But my favourite optimization was removing u-boot completely and booting
> > Linux kernel from ubl directly. Though this is not an option for
> > everyone.
> 
> What did you do for this? Any UBL patch available to take a look at?
> 

There was an C example at [1] which I stole most of the bits but I can not 
find that example at the moment. I attached my code to the end of this e-mail. 
Then all I need to do is call following from ubl.c:

 extern int start_linux(void); start_linux();

If you want to look at my complete UBL, I can send it to you privately.(not to 
waste list bw) I have a local git tree for that. In my tree I have LCD and 
EDMA support for UBL as well. But my tree is for a custom DM6446 board, no EVM 
support in it.

Regards,
Caglar

[1] http://www.arm.linux.org.uk/developer/booting.php

> Theo
> 
> 
> DISCLAIMER:
> Unless indicated otherwise, the information contained in this message is
>  privileged and confidential, and is intended only for the use of the
>  addressee(s) named above and others who have been specifically authorized
>  to receive it. If you are not the intended recipient, you are hereby
>  notified that any dissemination, distribution or copying of this message
>  and/or attachments is strictly prohibited. The company accepts no
>  liability for any damage caused by any virus transmitted by this email.
>  Furthermore, the company does not warrant a proper and complete
>  transmission of this information, nor does it accept liability for any
>  delays. If you have received this message in error, please contact the
>  sender and delete the message. Thank you.
> 
#include "config.h"
/* list of possible tags */
#define ATAG_NONE       0x00000000
#define ATAG_CORE       0x54410001
#define ATAG_MEM        0x54410002
#define ATAG_VIDEOTEXT  0x54410003
#define ATAG_RAMDISK    0x54410004
#define ATAG_INITRD2    0x54420005
#define ATAG_SERIAL     0x54410006
#define ATAG_REVISION   0x54410007
#define ATAG_VIDEOLFB   0x54410008
#define ATAG_CMDLINE    0x54410009

#define u32_t unsigned int
#define u32 unsigned int
#define u16 unsigned short
#define u8 unsigned char

/* structures for each atag */
struct atag_header {
        u32 size; /* length of tag in words including this header */
        u32 tag;  /* tag type */
};

struct atag_core {
        u32 flags;
        u32 pagesize;
        u32 rootdev;
};

struct atag_mem {
        u32     size;
        u32     start;
};

struct atag_videotext {
        u8              x;
        u8              y;
        u16             video_page;
        u8              video_mode;
        u8              video_cols;
        u16             video_ega_bx;
        u8              video_lines;
        u8              video_isvga;
        u16             video_points;
};

struct atag_ramdisk {
        u32 flags;
        u32 size;
        u32 start;
};

struct atag_initrd2 {
        u32 start;
        u32 size;
};

struct atag_serialnr {
        u32 low;
        u32 high;
};

struct atag_revision {
        u32 rev;
};

struct atag_videolfb {
        u16             lfb_width;
        u16             lfb_height;
        u16             lfb_depth;
        u16             lfb_linelength;
        u32             lfb_base;
        u32             lfb_size;
        u8              red_size;
        u8              red_pos;
        u8              green_size;
        u8              green_pos;
        u8              blue_size;
        u8              blue_pos;
        u8              rsvd_size;
        u8              rsvd_pos;
};

struct atag_cmdline {
        char    cmdline[1];
};

struct atag {
        struct atag_header hdr;
        union {
                struct atag_core         core;
                struct atag_mem          mem;
                struct atag_videotext    videotext;
                struct atag_ramdisk      ramdisk;
                struct atag_initrd2      initrd2;
                struct atag_serialnr     serialnr;
                struct atag_revision     revision;
                struct atag_videolfb     videolfb;
                struct atag_cmdline      cmdline;
        } u;
};


#define tag_next(t)     ((struct atag *)((u32 *)(t) + (t)->hdr.size))
#define tag_size(type)  ((sizeof(struct atag_header) + sizeof(type)) >> 2)
static struct atag *params; /* used to point at the current tag */

static void
setup_core_tag(void * address,long pagesize)
{
    params = (struct atag *)address;         /* Initialise parameters to start at given address */

    params->hdr.tag = ATAG_CORE;            /* start with the core tag */
    params->hdr.size = tag_size(struct atag_core); /* size the tag */

    params->u.core.flags = 1;               /* ensure read-only */
    params->u.core.pagesize = pagesize;     /* systems pagesize (4k) */
    params->u.core.rootdev = 0;             /* zero root device (typicaly overidden from commandline )*/

    params = tag_next(params);              /* move pointer to next tag */
}

static void
setup_mem_tag(u32_t start, u32_t len)
{
    params->hdr.tag = ATAG_MEM;             /* Memory tag */
    params->hdr.size = tag_size(struct atag_mem);  /* size tag */

    params->u.mem.start = start;            /* Start of memory area (physical address) */
    params->u.mem.size = len;               /* Length of area */

    params = tag_next(params);              /* move pointer to next tag */
}

u32 strlen(const char *s)
{
	const char *sc;

	for (sc = s; *sc != '\0'; ++sc)
		/* nothing */;
	return sc - s;
}

char *strncpy(char *dest, const char *src, u32 count)
{
	char *tmp = dest;

	while (count) {
		if ((*tmp = *src) != 0)
			src++;
		tmp++;
		count--;
	}
	return dest;
}

static void
setup_cmdline_tag(const char * line)
{
    int linelen = strlen(line);

    if(!linelen)
        return;                             /* do not insert a tag for an empty commandline */

    params->hdr.tag = ATAG_CMDLINE;         /* Commandline tag */
    params->hdr.size = (sizeof(struct atag_header) + linelen + 1 + 4) >> 2;

    strncpy(params->u.cmdline.cmdline, line, linelen); /* place commandline into tag */

    params = tag_next(params);              /* move pointer to next tag */
}

static void
setup_end_tag(void)
{
    params->hdr.tag = ATAG_NONE;            /* Empty tag ends list */
    params->hdr.size = 0;                   /* zero length */
}


#define DRAM_BASE 0x80000000
#define IMAGE_LOAD_ADDRESS DRAM_BASE + 0x8000
#define MACH_TYPE_DAVINCI_BEGINNING    1849

static void
setup_tags(u32 parameters)
{
    setup_core_tag((void *)parameters, 4096);       /* standard core tag 4k pagesize */
    setup_mem_tag(DRAM_BASE, 0x10000000);    /* 64Mb at 0x10000000 */
    setup_cmdline_tag(CMDLINE);    /* commandline setting root device */
    setup_end_tag();                    /* end of tags */
}

int
start_linux(void)
{
    void (*theKernel)(int zero, int arch, u32 params);
    u32 exec_at = (u32)-1;
    u32 parm_at = (u32)-1;
    u32 machine_type;

    exec_at = IMAGE_LOAD_ADDRESS;
    parm_at = DRAM_BASE + 0x100;

    //load_image(name, exec_at);              /* copy image into RAM */

    setup_tags(parm_at);                    /* sets up parameters */

    machine_type = MACH_TYPE_DAVINCI_BEGINNING;         /* get machine type */

    theKernel = (void (*)(int, int, u32))exec_at; /* set the kernel address */

    theKernel(0, machine_type, parm_at);    /* jump to kernel with register set */

    return 0;
}
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to