source: mainline/kernel/genarch/src/multiboot/multiboot.c@ accc088

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since accc088 was 5d8d71e, checked in by Jiri Svoboda <jirik.svoboda@…>, 17 years ago

Move multiboot parsing to genarch/*/multiboot and adapt it for use with both ia32 and amd64. Multiboot info parsing now supported on amd64, too.

  • Property mode set to 100644
File size: 4.1 KB
Line 
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 n Size of destination buffer.
46 * @param cmd_line Input string (the command line).
47 *
48 */
49static void extract_command(char *buf, size_t n, const char *cmd_line)
50{
51 const char *start, *end, *cp;
52 size_t max_len;
53
54 /* Find the first space. */
55 end = strchr(cmd_line, ' ');
56 if (end == NULL)
57 end = cmd_line + strlen(cmd_line);
58
59 /*
60 * Find last occurence of '/' before 'end'. If found, place start at
61 * next character. Otherwise, place start at beginning of buffer.
62 */
63 cp = end;
64 start = buf;
65 while (cp != start) {
66 if (*cp == '/') {
67 start = cp + 1;
68 break;
69 }
70 --cp;
71 }
72
73 /* Copy the command and null-terminate the string. */
74 max_len = min(n - 1, (size_t) (end - start));
75 strncpy(buf, start, max_len + 1);
76 buf[max_len] = '\0';
77}
78
79/** Parse multiboot information structure.
80 *
81 * If @a signature does not contain a valid multiboot signature,
82 * assumes no multiboot information is available.
83 *
84 * @param signature Should contain the multiboot signature.
85 * @param mi Pointer to the multiboot information structure.
86 */
87void multiboot_info_parse(uint32_t signature, const multiboot_info_t *mi)
88{
89 uint32_t flags;
90 multiboot_mod_t *mods;
91 uint32_t i;
92
93 if (signature == MULTIBOOT_LOADER_MAGIC)
94 flags = mi->flags;
95 else {
96 /* No multiboot info available. */
97 flags = 0;
98 }
99
100 /* Copy module information. */
101
102 if ((flags & MBINFO_FLAGS_MODS) != 0) {
103 init.cnt = mi->mods_count;
104 mods = (multiboot_mod_t *) MULTIBOOT_PTR(mi->mods_addr);
105
106 for (i = 0; i < init.cnt; i++) {
107 init.tasks[i].addr = PA2KA(mods[i].start);
108 init.tasks[i].size = mods[i].end - mods[i].start;
109
110 /* Copy command line, if available. */
111 if (mods[i].string) {
112 extract_command(init.tasks[i].name,
113 CONFIG_TASK_NAME_BUFLEN,
114 MULTIBOOT_PTR(mods[i].string));
115 } else
116 init.tasks[i].name[0] = '\0';
117 }
118 } else
119 init.cnt = 0;
120
121 /* Copy memory map. */
122
123 int32_t mmap_length;
124 multiboot_mmap_t *mme;
125 uint32_t size;
126
127 if ((flags & MBINFO_FLAGS_MMAP) != 0) {
128 mmap_length = mi->mmap_length;
129 mme = MULTIBOOT_PTR(mi->mmap_addr);
130 e820counter = 0;
131
132 i = 0;
133 while (mmap_length > 0) {
134 e820table[i++] = mme->mm_info;
135
136 /* Compute address of next structure. */
137 size = sizeof(mme->size) + mme->size;
138 mme = ((void *) mme) + size;
139 mmap_length -= size;
140 }
141
142 e820counter = i;
143 } else
144 e820counter = 0;
145}
146
147/** @}
148 */
Note: See TracBrowser for help on using the repository browser.