- Implemented execp*.
[planlOS.git] / system / kernel / ke / start.c
blob931aa53fc4378274db7032ad2af53e2e99c4bb7e
1 /*
2 Copyright (C) 2008 Mathias Gottschlag
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in the
6 Software without restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8 Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include "ke/debug.h"
23 #include "ke/gdt.h"
24 #include "ke/apic.h"
25 #include "ke/multiboot.h"
26 #include "ke/interrupts.h"
27 #include "ke/smp.h"
28 #include "ke/timer.h"
29 #include "ke/pci.h"
30 #include "ke/process.h"
31 #include "mm/memory.h"
32 #include "ke/module.h"
33 #include "fs/fs.h"
34 #include "fs/devfs.h"
35 #include "ke/elf.h"
36 #include "sys/pipe.h"
37 #include "sys/terminal.h"
38 #include "sys/serial.h"
39 #include "net/net.h"
40 #include <string.h>
41 #include <stdio.h>
42 #include <stdlib.h>
44 static MultibootInfo *mbinfo;
46 void kernel_phys_start();
47 void kernel_phys_end();
49 static void keInit2(void)
51 keInitKernelSymbols(mbinfo);
52 keInitPCI();
53 fsInit();
54 fsInitDevFS();
55 sysInitPipe();
56 netInit();
57 FsFileSystemDriver *devfs = fsGetDriver("devfs");
58 if (!devfs)
60 // TODO: Panic
61 kePrint("devfs not available.\n");
62 while (1);
64 fsMount(devfs, "/dev/", 0, 0);
65 sysInitSerial();
66 sysInitTerminals();
67 keInitModules(mbinfo);
69 // Map CDROM
70 FsFileSystemDriver *iso9660 = fsGetDriver("iso9660");
71 if (!iso9660)
73 // TODO: Panic
74 kePrint("iso9660 not available.\n");
75 while (1);
77 fsMount(iso9660, "/", "/dev/cdrom0", 0);
78 FsFileHandle *testfile = fsOpen("/boot/grub/menu.lst", FS_OPEN_READ);
79 if (!testfile)
81 kePrint("Could not open test file.\n");
83 else
85 char *test = malloc(20);
86 int read = fsRead(testfile, test, 19, 1);
87 kePrint("Read %d bytes.\n", read);
88 test[read] = 0;
89 kePrint("Read: \"%s\"\n", test);
90 fsClose(testfile);
91 free(test);
94 // Map /tmp
95 FsFileSystemDriver *ramdisk = fsGetDriver("ramdisk");
96 if (!ramdisk)
98 // TODO: Panic
99 kePrint("ramdisk not available.\n");
100 while (1);
102 fsMount(ramdisk, "/tmp/", 0, 0);
104 kePrint("Done.\n");
106 // Load initial process
107 FsFileHandle *initfile = fsOpen("/bin/shell", FS_OPEN_READ);
108 if (!initfile)
110 kePrint("Could not open initial program.\n");
111 while (1);
113 int size = fsSeek(initfile, 0, 2);
114 kePrint("File size: %d bytes.\n", size);
115 fsSeek(initfile, 0, 0);
116 char *program = malloc(size);
117 if (fsRead(initfile, program, size, 1) != size)
119 kePrint("Could not read whole program.\n");
120 fsClose(initfile);
121 while (1);
124 // Start initial processes
125 int i;
126 char terminal[11];
127 for (i = 0; i < 8; i++)
129 snprintf(terminal, 11, "/dev/tty%d", i);
130 KeProcess *process = keCreateProcess();
131 FsFileHandle *stdin = fsProcessOpen(process, terminal, FS_OPEN_READ);
132 process->fd[0] = stdin;
133 FsFileHandle *stdout = fsProcessOpen(process, terminal, FS_OPEN_WRITE);
134 process->fd[1] = stdout;
135 FsFileHandle *stderr = fsProcessOpen(process, terminal, FS_OPEN_WRITE);
136 process->fd[2] = stderr;
137 keElfMapProgram(&process->memory, program, size);
138 uintptr_t entry = ((ElfHeader*)program)->e_entry;
139 keCreateThread(process, entry, 4, 0, 0, 0, 0);
142 free(program);
143 fsClose(initfile);
145 keExitThread();
148 void keInit(int magic, MultibootInfo *info)
150 char *vidmem = (char*)0xC00B8000;
151 memset(vidmem, 0, 160 * 25);
153 keInstallStartupGDT();
154 kePrintInit();
155 keInitPIC();
156 if (!CHECK_FLAG(info->flags, 5))
158 kePrint("Error: no symbols available.\n");
159 while (1);
162 uintptr_t kernel_begin = ((uintptr_t)kernel_phys_start & ~0xFFF) + 0xC0000000;
163 uintptr_t kernel_end = (((uintptr_t)kernel_phys_end + 4095) & ~0xFFF) + 0xC0000000;
164 mmInitMemoryManager(info, kernel_begin, kernel_end);
165 // Remap multiboot struct
166 uintptr_t info_addr = mmFindFreeKernelPages(MM_MAX_KERNEL_PAGE,
167 MM_MIN_KERNEL_PAGE, 1, 0x1000);
168 mmMapKernelMemory((uintptr_t)info & ~0xFFF, info_addr,
169 MM_MAP_READ | MM_MAP_WRITE);
170 info_addr += (uintptr_t)info & 0xFFF;
171 info = (void*)info_addr;
172 mbinfo = info;
174 keAPICInit();
175 keInitSMP();
176 keInstallGDT();
177 keInitTimer(100);
178 keInitProcessManager();
180 // Initial kernel thread
181 keCreateKernelThread((uintptr_t)keInit2, 0);
183 // Start kernel
184 kePrint("Installing timer.\n");
185 keInstallTimer();
186 kePrint("Starting APs.\n");
187 keStartAPs();
188 kePrint("Enabling interrupts.\n");
189 asm("sti");
191 while (1) asm("hlt");