Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / bsp / boot / common / load.c @ 03e9c04a

History | View | Annotate | Download (5.37 KB)

1 03e9c04a Brad Neuman
/*-
2
 * Copyright (c) 2005-2009, Kohsuke Ohtani
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
/*
31
 * load.c - Load OS modules
32
 */
33
34
#include <boot.h>
35
#include <load.h>
36
#include <sys/ar.h>
37
#include <sys/bootinfo.h>
38
39
/* forward declarations */
40
static int        load_module(struct ar_hdr *, struct module *);
41
static void        setup_bootdisk(struct ar_hdr *);
42
43
paddr_t        load_base;        /* current load address */
44
paddr_t        load_start;        /* start address for loading */
45
int        nr_img;                /* number of module images */
46
47
48
/*
49
 * Load OS images - kernel, driver and boot tasks.
50
 *
51
 * It reads each module file image and copy it to the appropriate
52
 * memory area. The image is built as generic an archive (.a) file.
53
 *
54
 * The image information is stored into the boot information area.
55
 */
56
void
57
load_os(void)
58
{
59
        char *hdr;
60
        struct bootinfo *bi = bootinfo;
61
        struct module *m;
62
        char *magic;
63
        int i;
64
        long len;
65
66
        /*
67
         * Initialize our data.
68
         */
69
        load_base = 0;
70
        load_start = 0;
71
        nr_img = 0;
72
73
        /*
74
         *  Sanity check of archive image.
75
         */
76
        magic = (char *)kvtop(CONFIG_BOOTIMG_BASE);
77
        if (strncmp(magic, ARMAG, 8))
78
                panic("Invalid OS image");
79
80
        /*
81
         * Load kernel module.
82
         */
83
        hdr = (char *)((paddr_t)magic + 8);
84
        if (load_module((struct ar_hdr *)hdr, &bi->kernel))
85
                panic("Can not load kernel");
86
87
        /*
88
         * Load driver module.
89
         */
90
        len = atol((char *)&((struct ar_hdr *)hdr)->ar_size);
91
        len += len % 2;        /* even alignment */
92
        if (len == 0)
93
                panic("Invalid driver image");
94
        hdr = (char *)((paddr_t)hdr + sizeof(struct ar_hdr) + len);
95
        if (load_module((struct ar_hdr *)hdr, &bi->driver))
96
                panic("Can not load driver");
97
98
        /*
99
         * Load boot tasks.
100
         */
101
        i = 0;
102
        m = (struct module *)&bi->tasks[0];
103
        while (1) {
104
                /* Proceed to next archive header */
105
                len = atol((char *)&((struct ar_hdr *)hdr)->ar_size);
106
                len += len % 2;        /* even alignment */
107
                if (len == 0)
108
                        break;
109
                hdr = (char *)((paddr_t)hdr + sizeof(struct ar_hdr) + len);
110
111
                /* Check archive header */
112
                if (strncmp((char *)&((struct ar_hdr *)hdr)->ar_fmag,
113
                            ARFMAG, 2))
114
                        break;
115
116
                /* Load boot disk image */
117
                if (!strncmp((char *)&((struct ar_hdr *)hdr)->ar_name,
118
                            "bootdisk.a", 10)) {
119
                        setup_bootdisk((struct ar_hdr *)hdr);
120
                        continue;
121
                }
122
123
                /* Load task */
124
                if (load_module((struct ar_hdr *)hdr, m))
125
                        break;
126
                i++;
127
                m++;
128
        }
129
130
        bi->nr_tasks = i;
131
132
        if (bi->nr_tasks == 0)
133
                panic("No boot task found!");
134
135
        /*
136
         * Reserve single memory block for all boot modules.
137
         * This includes kernel, driver, and boot tasks.
138
         */
139
        i = bi->nr_rams;
140
        bi->ram[i].base = load_start;
141
        bi->ram[i].size = (size_t)(load_base - load_start);
142
        bi->ram[i].type = MT_RESERVED;
143
        bi->nr_rams++;
144
}
145
146
/*
147
 * Load module.
148
 * Return 0 on success, -1 on failure.
149
 */
150
static int
151
load_module(struct ar_hdr *hdr, struct module *m)
152
{
153
        char *c;
154
155
        if (strncmp((char *)&hdr->ar_fmag, ARFMAG, 2)) {
156
                DPRINTF(("Invalid image %s\n", hdr->ar_name));
157
                return -1;
158
        }
159
        strlcpy(m->name, hdr->ar_name, sizeof(m->name));
160
        c = m->name;
161
        while (*c != '/' && *c != ' ')
162
                c++;
163
        *c = '\0';
164
165
         DPRINTF(("loading: hdr=%lx module=%lx name=%s\n",
166
                 (paddr_t)hdr, (paddr_t)m, m->name));
167
168
        if (load_elf((char *)hdr + sizeof(struct ar_hdr), m))
169
                panic("Load error");
170
171
        return 0;
172
}
173
174
/*
175
 * Setup boot disk
176
 */
177
static void
178
setup_bootdisk(struct ar_hdr *hdr)
179
{
180
        struct bootinfo *bi = bootinfo;
181
        paddr_t base;
182
        size_t size;
183
184
        /*
185
         * Store image information.
186
         */
187
        if (strncmp((char *)&hdr->ar_fmag, ARFMAG, 2)) {
188
                DPRINTF(("Invalid bootdisk image\n"));
189
                return;
190
        }
191
        size = (size_t)atol((char *)&hdr->ar_size);
192
        size += size % 2;        /* even alignment */
193
        if (size == 0) {
194
                DPRINTF(("Size of bootdisk is zero\n"));
195
                return;
196
        }
197
        base = (paddr_t)hdr + sizeof(struct ar_hdr);
198
        bi->bootdisk.base = base;
199
        bi->bootdisk.size = size;
200
201
#if !defined(CONFIG_ROMBOOT)
202
        /*
203
         * Reserve memory for boot disk if the image
204
         * was copied to RAM.
205
         */
206
        bi->ram[bi->nr_rams].base = base;
207
        bi->ram[bi->nr_rams].size = size;
208
        bi->ram[bi->nr_rams].type = MT_BOOTDISK;
209
        bi->nr_rams++;
210
#endif
211
        DPRINTF(("bootdisk base=%lx size=%lx\n",
212
                 bi->bootdisk.base, bi->bootdisk.size));
213
}