Subversion Repositories freemyipod

Rev

Rev 881 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
881 theseven 1
#include "global.h"
2
#include "app/umsboot/main.h"
3
#include "app/main.h"
4
#include "app/umsboot/usbglue.h"
5
#include "app/umsboot/ums.h"
6
#include "sys/time.h"
7
#include "sys/util.h"
8
#include "protocol/usb/usb.h"
9
 
10
#ifdef UMSBOOT_HAVE_CONSOLE
11
#include "interface/console/console.h"
12
#include "app/umsboot/console.h"
13
#endif
14
 
15
 
16
static uint16_t swapmap[RAMDISK_SECTORS] __attribute__((aligned(CACHEALIGN_SIZE)));
17
static uint16_t swaprev[RAMDISK_SECTORS] __attribute__((aligned(CACHEALIGN_SIZE)));
18
static char swapbuf[RAMDISK_SECTORSIZE] __attribute__((aligned(CACHEALIGN_SIZE)));
19
static uint16_t newfat[RAMDISK_SECTORS] __attribute__((aligned(CACHEALIGN_SIZE)));
20
static char newdir[RAMDISK_SECTORSIZE] __attribute__((aligned(CACHEALIGN_SIZE)));
21
static int fatsectors;
22
 
23
 
24
int fat16_calc_fatsectors(int sectors)
25
{
26
    uint32_t fatsectors = 1;
27
    uint32_t oldfatsectors = 0;
28
    uint32_t clustercount;
29
    while (fatsectors != oldfatsectors)
30
    {
31
        oldfatsectors = fatsectors;
32
        clustercount = sectors - fatsectors - 2;
33
        fatsectors = (2 * (clustercount + 2) + RAMDISK_SECTORSIZE - 1) / RAMDISK_SECTORSIZE;
34
    }
35
    return fatsectors;
36
}
37
 
38
int fat16_write_mbr(uint8_t* buffer, int sectors)
39
{
40
    uint32_t fatsectors = fat16_calc_fatsectors(sectors);
41
    memset(buffer, 0, RAMDISK_SECTORSIZE);
42
    memcpy(buffer, "\xeb\x58\x00MSWIN5.0", 0xb);
43
    buffer[0xb] = RAMDISK_SECTORSIZE & 0xff;
44
    buffer[0xc] = RAMDISK_SECTORSIZE >> 8;
45
    buffer[0xd] = 1;
46
    ((uint16_t*)buffer)[7] = 1;
47
    buffer[0x10] = 1;
48
    buffer[0x11] = (RAMDISK_SECTORSIZE >> 5) & 0xff;
49
    buffer[0x12] = RAMDISK_SECTORSIZE >> 13;
50
    buffer[0x13] = sectors & 0xff;
51
    buffer[0x14] = sectors >> 8;
52
    buffer[0x15] = 0xf8;
53
    buffer[0x18] = 0x3f;
54
    buffer[0x1a] = 0xff;
55
    ((uint16_t*)buffer)[0xb] = fatsectors;
56
    memcpy(&buffer[0x24], "\x80\0\x29UBRDUMSboot    FAT16   ", 0x1a);
57
    ((uint16_t*)buffer)[0xff] = 0xaa55;
58
    return fatsectors;
59
}
60
 
61
void fat16_write_fat(uint8_t* buffer, int sectors)
62
{
63
    memset(buffer, 0, sectors * RAMDISK_SECTORSIZE);
64
    *((uint32_t*)buffer) = 0xfffffff8;
65
}
66
 
67
void fat16_write_rootdir(uint8_t* buffer)
68
{
69
    memset(buffer, 0, RAMDISK_SECTORSIZE);
70
    memcpy(buffer, "UMSboot    \x08", 12);
71
}
72
 
73
void swap(src, dest)
74
{
75
    memcpy(swapbuf, RAMDISK[dest], RAMDISK_SECTORSIZE);
76
    uint16_t srcmap = swapmap[src];
77
    uint16_t destmap = swaprev[dest];
78
    memcpy(RAMDISK[dest], RAMDISK[srcmap], RAMDISK_SECTORSIZE);
79
    swapmap[src] = dest;
80
    swaprev[dest] = src;
81
    memcpy(RAMDISK[srcmap], swapbuf, RAMDISK_SECTORSIZE);
82
    swaprev[srcmap] = destmap;
83
    swapmap[destmap] = srcmap;
84
}
85
 
86
int main()
87
{
88
    int i;
89
#ifdef UMSBOOT_HAVE_CONSOLE
90
    umsboot_console_init();
91
#endif
92
    fatsectors = fat16_write_mbr(RAMDISK[0], RAMDISK_SECTORS);
93
    fat16_write_fat(RAMDISK[1], fatsectors);
94
    fat16_write_rootdir(RAMDISK[1 + fatsectors]);
95
    for (i = 0; i < RAMDISK_SECTORS; i++) swapmap[i] = i;
96
    memcpy(swaprev, swapmap, sizeof(swaprev));
97
    while (true)
98
    {
99
        ums_ejected = false;
100
        usb_init(&usb_data);
101
        while (!ums_ejected) idle();
102
        udelay(100000);
103
        usb_exit(&usb_data);
104
#ifdef UMSBOOT_HAVE_CONSOLE
105
        console_puts(&umsboot_console, "\nLoading UBI file...\n");
106
        console_flush(&umsboot_console);
107
#endif
108
        int found = 0;
909 user890104 109
        uint16_t ubicluster = 0;
110
        uint32_t ubisize = 0;
881 theseven 111
        uint16_t cluster = 0;
112
        uint16_t totalclusters = 0;
113
        for (i = 0; i < RAMDISK_SECTORSIZE; i += 32)
114
            if (!RAMDISK[1 + fatsectors][i]) break;
115
            else if (RAMDISK[1 + fatsectors][i] == 0xe5) continue;
116
            else if (((((uint32_t*)RAMDISK[1 + fatsectors])[(i + 8) >> 2]) & 0xffffff) == 0x494255)
117
            {
909 user890104 118
                ubicluster = ((uint16_t*)RAMDISK[1 + fatsectors])[(i + 26) >> 1];
119
                ubisize = ((uint32_t*)RAMDISK[1 + fatsectors])[(i + 28) >> 2];
881 theseven 120
                RAMDISK[1 + fatsectors][i] = 0xe5;
121
                found++;
122
            }
909 user890104 123
            else if ((cluster = ((uint16_t*)RAMDISK[1 + fatsectors])[(i + 26) >> 1]))
124
                while (cluster != 0xffff)
125
                {
126
                    cluster = ((uint16_t*)RAMDISK[1])[cluster];
127
                    totalclusters++;
128
                }
881 theseven 129
        if (!found)
130
        {
131
#ifdef UMSBOOT_HAVE_CONSOLE
132
            console_puts(&umsboot_console, "No UBI file found!\nPlease retry.\n");
133
            console_flush(&umsboot_console);
134
#endif
135
            continue;
136
        }
137
        if (found != 1)
138
        {
139
#ifdef UMSBOOT_HAVE_CONSOLE
140
            console_puts(&umsboot_console, "Multiple UBI files found!\nPlease copy exactly one.\nPlease retry.\n");
141
            console_flush(&umsboot_console);
142
#endif
143
            continue;
144
        }
909 user890104 145
        if (!ubisize || !ubicluster)
881 theseven 146
        {
147
#ifdef UMSBOOT_HAVE_CONSOLE
148
            console_puts(&umsboot_console, "UBI file is empty!\nPlease retry.\n");
149
            console_flush(&umsboot_console);
150
#endif
151
            continue;
152
        }
153
        uint16_t dest = 0;
909 user890104 154
        while (ubicluster != 0xffff)
881 theseven 155
        {
909 user890104 156
            swap(fatsectors + ubicluster, dest++);
157
            ubicluster = ((uint16_t*)RAMDISK[swapmap[1 + (ubicluster / (RAMDISK_SECTORSIZE / 2))]])
158
                                            [ubicluster % (RAMDISK_SECTORSIZE / 2)];
881 theseven 159
        }
160
#ifdef UMSBOOT_HAVE_CONSOLE
161
        console_puts(&umsboot_console, "Rearranging files...\n");
162
        console_flush(&umsboot_console);
163
#endif
164
        uint16_t offset = RAMDISK_SECTORS - totalclusters - 2;
165
        memset(newfat, 0, sizeof(newfat));
166
        memset(newdir, 0, sizeof(newdir));
167
        newfat[0] = ((uint16_t*)RAMDISK[swapmap[1]])[0];
168
        newfat[1] = ((uint16_t*)RAMDISK[swapmap[1]])[1];
169
        dest = 2;
170
        int newptr = 0;
171
        for (i = 0; i < RAMDISK_SECTORSIZE; i += 32)
172
            if (!RAMDISK[swapmap[1 + fatsectors]][i]) break;
173
            else if (RAMDISK[swapmap[1 + fatsectors]][i] == 0xe5) continue;
174
            else
175
            {
176
                memcpy(&newdir[newptr], &RAMDISK[swapmap[1 + fatsectors]][i], 0x20);
177
                cluster = ((uint16_t*)newdir)[(newptr + 26) >> 1];
178
                if (cluster)
179
                {
180
                    ((uint16_t*)newdir)[(newptr + 26) >> 1] = dest;
181
                    while (cluster != 0xffff)
182
                    {
183
                        swap(fatsectors + cluster, offset + dest++);
184
                        cluster = ((uint16_t*)RAMDISK[swapmap[1 + (cluster / (RAMDISK_SECTORSIZE / 2))]])
185
                                                     [cluster % (RAMDISK_SECTORSIZE / 2)];
186
                        if (cluster == 0xffff) newfat[dest - 1] = 0xffff;
187
                        else newfat[dest - 1] = dest;
188
                    }
189
                }
190
                newptr += 0x20;
191
            }
192
        fatsectors = (2 * (totalclusters + 2) + RAMDISK_SECTORSIZE - 1) / RAMDISK_SECTORSIZE;
193
        RAMDISK_PTR = RAMDISK[offset - fatsectors];
194
        memcpy(RAMDISK[offset + 1], newdir, RAMDISK_SECTORSIZE);
195
        memcpy(RAMDISK[offset - fatsectors + 1], newfat, fatsectors * RAMDISK_SECTORSIZE);
196
        fat16_write_mbr(RAMDISK_PTR, totalclusters + fatsectors + 2);
197
#ifdef UMSBOOT_HAVE_CONSOLE
198
        console_puts(&umsboot_console, "Booting UBI file...");
199
        console_flush(&umsboot_console);
200
#endif
909 user890104 201
#ifdef DEBUG
202
        continue;
203
#else
881 theseven 204
        execfirmware(RAMDISK[0]);
909 user890104 205
#endif
881 theseven 206
    }
207
}