Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
90 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
427 farthen 6
//    This file is part of emCORE.
90 theseven 7
//
427 farthen 8
//    emCORE is free software: you can redistribute it and/or
90 theseven 9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
427 farthen 13
//    emCORE is distributed in the hope that it will be useful,
90 theseven 14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
427 farthen 19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
90 theseven 20
//
21
//
22
 
23
 
24
#include "global.h"
25
#include "console.h"
26
#include "execimage.h"
92 theseven 27
#include "mmu.h"
90 theseven 28
 
29
 
453 theseven 30
struct scheduler_thread* execimage(void* image, bool copy)
90 theseven 31
{
453 theseven 32
    struct emcoreapp_header* header = (struct emcoreapp_header*)image;
33
    if (memcmp(header, "emCOexec", 8))
90 theseven 34
    {
453 theseven 35
        cprintf(CONSOLE_BOOT, "execimage: Bad signature: "
90 theseven 36
                              "%02X %02X %02X %02X %02X %02X %02X %02X\n",
37
                header->signature[0], header->signature[1], header->signature[2],
38
                header->signature[3], header->signature[4], header->signature[5],
39
                header->signature[6], header->signature[7]);
453 theseven 40
        return NULL;
90 theseven 41
    }
453 theseven 42
    if (header->version != EMCOREAPP_HEADER_VERSION)
90 theseven 43
    {
44
        cprintf(CONSOLE_BOOT, "execimage: Unsupported version! (%08X)\n", header->version);
453 theseven 45
        return NULL;
90 theseven 46
    }
453 theseven 47
    off_t offset = header->textstart;
48
    size_t textsize = header->textsize;
49
    size_t bsssize = header->bsssize;
50
    size_t stacksize = header->stacksize;
51
	off_t entrypoint = header->entrypoint;
52
	off_t relocstart = header->relocstart - offset;
53
	uint32_t reloccount = header->reloccount;
54
	bool compressed = header->flags & EMCOREAPP_FLAG_COMPRESSED;
55
    size_t finalsize = textsize + bsssize + stacksize;
56
    size_t datasize = relocstart + reloccount * 4;
57
    size_t tempsize = MAX(finalsize, datasize);
58
    if (compressed)
90 theseven 59
    {
453 theseven 60
        void* alloc = malloc(tempsize);
61
        if (!alloc)
62
        {
63
            cprintf(CONSOLE_BOOT, "execimage: Out of memory!\n");
64
            return NULL;
65
        }
66
        uint32_t decompsize;
67
        if (ucl_decompress(image + offset, datasize, alloc, &decompsize))
68
        {
69
            cprintf(CONSOLE_BOOT, "execimage: Decompression failed!\n");
70
            free(alloc);
71
            return NULL;
72
        }
73
        if (datasize != decompsize)
74
        {
75
            cprintf(CONSOLE_BOOT, "execimage: Decompressed size mismatch!\n");
76
            free(alloc);
77
            return NULL;
78
        }
79
        if (!copy) free(image);
80
        image = alloc;
90 theseven 81
    }
453 theseven 82
    else if (copy)
83
    {
84
        void* alloc = malloc(tempsize);
85
        if (!alloc)
86
        {
87
            cprintf(CONSOLE_BOOT, "execimage: Out of memory!\n");
88
            return NULL;
89
        }
90
        memcpy(alloc, image + offset, datasize);
91
        image = alloc;
92
    }
93
    else
94
    {
95
        memcpy(image, image + offset, datasize);
96
        image = realloc(image, tempsize);
97
        if (!image)
98
        {
99
            cprintf(CONSOLE_BOOT, "execimage: Out of memory!\n");
100
            return NULL;
101
        }
102
    }
103
    for (; reloccount; reloccount--, relocstart += 4)
104
    {
105
        off_t reloc = *((off_t*)(image + relocstart));
106
        uint32_t data = *((uint32_t*)(image + reloc));
107
        *((void**)(image + reloc)) = image + data;
108
    }
109
    if (tempsize != finalsize) realloc(image, finalsize); /* Can only shrink => safe */
92 theseven 110
    clean_dcache();
111
    invalidate_icache();
453 theseven 112
    struct scheduler_thread* thread = thread_create(NULL, NULL, image + entrypoint,
113
                                                    image + textsize + bsssize, stacksize,
114
                                                    USER_THREAD, 127, false);
115
    reownalloc(image, thread);
116
    thread_resume(thread);
117
    return thread;
90 theseven 118
}