2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
31 #include "init.conf.h"
33 static int sigusr1_count
;
36 * SIGUSR1 Handler. Is called when process finishs initialzation
37 * @param sig Signal. MUST be SIGUSR1
39 static void sigusr1_handler(int sig
) {
44 * Initializes Initialization ;)
46 static void init_init() {
47 signal(SIGUSR1
,sigusr1_handler
);
51 * Runs a program (Sends SIGCONT)
52 * @param name Name of program to run
54 static void init_run(const char *name
) {
55 pid_t pid
= getpidbyname(name
);
61 * Waits for a program to initialize
62 * @param name Name of program to wait for
63 * @return If waiting was successful or timeout occured
65 static int init_wait(const char *name
) {
67 const useconds_t timeout
= 10000; // 10 seconds
68 while (sigusr1_count
==0 && t
<timeout
) {
83 static exe_t
*exe_create(const char *file
) {
84 exe_t
*exe
= malloc(sizeof(exe_t
*));
87 exe
->data
= elf_create(file
);
88 if (exe
->data
!=NULL
) {
92 else elf_destroy((elf_t
*)exe
->data
);
99 static void *exe_load(exe_t
*exe
,pid_t pid
) {
100 if (exe
->type
==EXE_ELF
) return elf_load((elf_t
*)exe
->data
,pid
);
104 static void exe_destroy(exe_t
*exe
) {
105 if (exe
->type
==EXE_ELF
) elf_destroy((elf_t
*)exe
->data
);
108 static pid_t
proc_fork(void *child_entry
) {
111 char *name
= getname(rpc_curpid
);
112 pid_t pid
= proc_create(name
,getuidbypid(rpc_curpid
),getgidbypid(rpc_curpid
),rpc_curpid
);
115 // Copy userspace memory
117 void **pages
= proc_mempagelist(rpc_curpid
,&num_pages
);
120 for (i
=0;i
<num_pages
;i
++) {
121 int writable
,swappable
;
122 void *srcp
= proc_memget(rpc_curpid
,pages
[i
],NULL
,&writable
,&swappable
,NULL
);
125 // Map parent's page to init
126 void *srcv
= proc_memmap(1,NULL
,srcp
,0,0,0);
128 // Allocate child's page in init's addrspace
129 void *dstv
= proc_memmap(1,NULL
,NULL
,1,0,0);
130 void *dstp
= mem_getphysaddr(dstv
);
132 // Map child's page to child
133 proc_memmap(pid
,pages
[i
],dstp
,writable
,swappable
,0);
136 memcpy(dstv
,srcv
,PAGE_SIZE
);
138 proc_memunmap(1,srcv
);
139 proc_memunmap(1,dstv
);
141 else proc_memmap(pid
,pages
[i
],NULL
,writable
,swappable
,0);
145 // Set entrypoint of child
146 proc_jump(pid
,child_entry
);
152 static int proc_exec(const char *file
,int var
) {
153 dbgmsg("proc_exec(%s,%d)\n",file
,var
);
155 char *_file
= strdup(file
);
156 proc_setname(rpc_curpid
,basename(_file
));
157 proc_setvar(rpc_curpid
,var
);
160 exe_t
*exe
= exe_create(file
);
162 // Remove old addrspace
164 void **pages
= proc_mempagelist(rpc_curpid
,&num_pages
);
166 for (i
=0;i
<num_pages
;i
++) proc_memfree(rpc_curpid
,pages
[i
]);
169 void *entrypoint
= exe_load(exe
,rpc_curpid
);
171 if (entrypoint
!=NULL
) {
172 proc_jump(rpc_curpid
,entrypoint
);
173 proc_createstack(rpc_curpid
);
176 dbgmsg("failed loading executable!");
177 dbgmsg("TODO: destroy process\n");
187 static void init_computer_shutdown() {
189 while ((child
= getchild(0))!=-1) kill(child
,SIGKILL
);
193 int main(int argc
,char *argv
[]) {
197 for (i
=0;INIT_PROGRAM(i
);i
++) {
198 //dbgmsg("init: starting %s...",INIT_PROGRAM(i));
199 init_run(INIT_PROGRAM(i
));
201 if (!init_wait(INIT_PROGRAM(i
))) {
202 dbgmsg("init: %s does not respond. initialization failed!\n",init_programs
[i
]);
207 if (strcmp(INIT_PROGRAM(i
),"iso9660")==0) {
208 // Initial mount of boot device
209 vfs_mount(BOOT_FS
,BOOT_MP
,BOOT_DEV
,BOOT_RO
);
214 rpc_func(proc_fork
,"i",sizeof(int));
215 rpc_func(proc_exec
,"$i",PATH_MAX
+sizeof(int));
216 rpc_func_create("computer_shutdown",init_computer_shutdown
,"",0);
218 init_run(INIT2_PROGRAM
);