2 * Copyright (c) 2006 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sys/platform/vkernel/platform/init.c,v 1.1 2006/12/04 18:04:04 dillon Exp $
45 static void init_sys_memory(const char *imageFile);
46 static void init_kern_memory(const char *imageFile);
47 static void init_rootdevice(const char *imageFile);
50 * Kernel startup for virtual kernels - standard main()
53 main(int ac, char **av)
55 const char *memImageFile;
56 const char *rootImageFile;
61 while ((c = getopt(ac, av, "vm:")) != -1) {
67 memImageFile = optarg;
70 rootImageFile = optarg;
73 Maxmem = strtoull(optarg, &suffix, 0);
90 usage("Bad maxmem option");
99 init_sys_memory(memImageFile);
101 init_rootdevice(rootImageFile);
107 * Initialize system memory. This is the virtual kernel's 'RAM'.
111 init_sys_memory(const char *imageFile)
116 * Figure out the system memory image size. If an image file was
117 * specified and -m was not specified, use the image file's size.
120 if (imageFile && stat(imageFile, &st) == 0 && Maxmem == 0)
121 Maxmem = (vm_paddr_t)st.st_size;
122 if ((imageFile == NULL || stat(imageFile, &st) < 0) && Maxmem == 0) {
123 err(1, "Cannot create new memory file unless "
124 "system memory size is specified with -m",
130 * Maxmem must be known at this time
132 if (Maxmem < 32 * 1024 * 1024 || (Maxmem & SEG_MASK)) {
133 err(1, "Bad maxmem specification: 32MB minimum, "
134 "multiples of %dMB only",
135 SEG_SIZE / 1024 / 1024);
140 * Generate an image file name if necessary, then open/create the
141 * file exclusively locked. Do not allow multiple virtual kernels
142 * to use the same image file.
144 if (imageFile == NULL)
145 asprintf(&imageFile, "/var/vkernel/image.%05d", (int)getpid());
146 fd = open(imageFile, O_RDWR|O_CREAT|O_EXLOCK|O_NONBLOCK, 0644);
147 if (fd < 0 || fstat(fd, &st) < 0) {
148 err(1, "Unable to open/create %s",
149 imageFile, strerror(errno));
154 * Truncate or extend the file as necessary.
156 if (st.st_size > Maxmem) {
157 ftruncate(fd, Maxmem);
158 } else if (st.st_size < Maxmem) {
160 off_t off = st.st_size & ~SEG_MASK;
162 printf("%s: Reserving blocks for memory image\n", imageFile);
163 zmem = malloc(SEG_SIZE);
164 bzero(zmem, SEG_SIZE);
166 while (off < Maxmem) {
167 if (write(fd, zmem, SEG_SIZE) != SEG_SIZE) {
168 err(1, "Unable to reserve blocks for memory image");
174 err(1, "Unable to reserve blocks for memory image");
181 * Initialize kernel memory. This reserves kernel virtual memory by using
186 init_kern_memory(void)
191 * Memory map our kernel virtual memory space. Note that the
192 * kernel image itself is not made part of this memory for the
195 base = mmap(NULL, KERNEL_KVA_SIZE, PROT_READ|PROT_WRITE,
196 MAP_FILE|MAP_VPAGETABLE, MemImageFd, 0);
197 if (base == MAP_FAILED) {
198 err(1, "Unable to mmap() kernel virtual memory!");
201 KvaBase = (vm_offset_t)base;
202 KvaSize = KERNEL_KVA_SIZE;
205 * Create a top-level page table self-mapping itself.
210 * The root filesystem path for the virtual kernel is optional. If specified
211 * it points to a filesystem image.
215 init_rootdevice(const char *imageFile)