Subversion Repositories HelenOS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4377 svoboda 1
/*
2
 * Copyright (c) 2009 Jiri Svoboda
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
 *
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
/** @addtogroup genarch
30
 * @{
31
 */
32
/** @file
33
 */
34
 
35
#include <genarch/multiboot/multiboot.h>
36
#include <arch/types.h>
37
#include <typedefs.h>
38
#include <config.h>
39
#include <string.h>
40
#include <macros.h>
41
 
42
/** Extract command name from the multiboot module command line.
43
 *
44
 * @param buf      Destination buffer (will always NULL-terminate).
45
 * @param sz       Size of destination buffer (in bytes).
46
 * @param cmd_line Input string (the command line).
47
 *
48
 */
49
static void extract_command(char *buf, size_t sz, const char *cmd_line)
50
{
51
    /* Find the first space. */
52
    const char *end = str_chr(cmd_line, ' ');
53
    if (end == NULL)
54
        end = cmd_line + str_size(cmd_line);
55
 
56
    /*
57
     * Find last occurence of '/' before 'end'. If found, place start at
58
     * next character. Otherwise, place start at beginning of buffer.
59
     */
60
    const char *cp = end;
61
    const char *start = buf;
62
 
63
    while (cp != start) {
64
        if (*cp == '/') {
65
            start = cp + 1;
66
            break;
67
        }
68
        cp--;
69
    }
70
 
71
    /* Copy the command. */
72
    str_ncpy(buf, sz, start, (size_t) (end - start));
73
}
74
 
75
/** Parse multiboot information structure.
76
 *
77
 * If @a signature does not contain a valid multiboot signature,
78
 * assumes no multiboot information is available.
79
 *
80
 * @param signature Should contain the multiboot signature.
81
 * @param mi        Pointer to the multiboot information structure.
82
 */
83
void multiboot_info_parse(uint32_t signature, const multiboot_info_t *mi)
84
{
85
    uint32_t flags;
86
 
87
    if (signature == MULTIBOOT_LOADER_MAGIC)
88
        flags = mi->flags;
89
    else {
90
        /* No multiboot info available. */
91
        flags = 0;
92
    }
93
 
94
    /* Copy module information. */
95
    uint32_t i;
96
    if ((flags & MBINFO_FLAGS_MODS) != 0) {
97
        init.cnt = min(mi->mods_count, CONFIG_INIT_TASKS);
98
        multiboot_mod_t *mods
99
            = (multiboot_mod_t *) MULTIBOOT_PTR(mi->mods_addr);
100
 
101
        for (i = 0; i < init.cnt; i++) {
102
            init.tasks[i].addr = PA2KA(mods[i].start);
103
            init.tasks[i].size = mods[i].end - mods[i].start;
104
 
105
            /* Copy command line, if available. */
106
            if (mods[i].string) {
107
                extract_command(init.tasks[i].name,
108
                    CONFIG_TASK_NAME_BUFLEN,
109
                    MULTIBOOT_PTR(mods[i].string));
110
            } else
111
                init.tasks[i].name[0] = 0;
112
        }
113
    } else
114
        init.cnt = 0;
115
 
116
    /* Copy memory map. */
117
 
118
    if ((flags & MBINFO_FLAGS_MMAP) != 0) {
119
        int32_t mmap_length = mi->mmap_length;
120
        multiboot_mmap_t *mme = MULTIBOOT_PTR(mi->mmap_addr);
121
        e820counter = 0;
122
 
123
        i = 0;
124
        while ((mmap_length > 0) && (i < MEMMAP_E820_MAX_RECORDS)) {
125
            e820table[i++] = mme->mm_info;
126
 
127
            /* Compute address of next structure. */
128
            uint32_t size = sizeof(mme->size) + mme->size;
129
            mme = ((void *) mme) + size;
130
            mmap_length -= size;
131
        }
132
 
133
        e820counter = i;
134
    } else
135
        e820counter = 0;
136
}
137
 
138
/** @}
139
 */