* Remove the debugging hack in procvm.c
[lunaix-os.git] / lunaix-os / kernel / lunad.c
1 #include <lunaix/boot_generic.h>
2 #include <lunaix/exec.h>
3 #include <lunaix/foptions.h>
4 #include <lunaix/fs.h>
5 #include <lunaix/fs/probe_boot.h>
6 #include <lunaix/fs/twifs.h>
7 #include <lunaix/spike.h>
8 #include <lunaix/syslog.h>
9 #include <lunaix/types.h>
10 #include <lunaix/owloysius.h>
11 #include <lunaix/sched.h>
12 #include <lunaix/kpreempt.h>
13
14 #include <klibc/string.h>
15
16 LOG_MODULE("PROC0")
17
18 void
19 init_platform();
20
21 int
22 mount_bootmedium()
23 {
24     struct v_dnode* dnode;
25     int errno = 0;
26     struct device* dev = probe_boot_medium();
27     if (!dev) {
28         ERROR("fail to acquire device. (%d)", errno);
29         return 0;
30     }
31
32     if ((errno = vfs_mount("/mnt/lunaix-os", "iso9660", dev, 0))) {
33         ERROR("fail to mount boot medium. (%d)", errno);
34         return 0;
35     }
36
37     return 1;
38 }
39
40 int
41 exec_initd()
42 {
43     int errno = 0;
44
45     if ((errno = exec_kexecve("/mnt/lunaix-os/usr/bin/init", NULL, NULL))) {
46         goto fail;
47     }
48
49     fail("should not reach");
50
51 fail:
52     ERROR("fail to load initd. (%d)", errno);
53     return 0;
54 }
55
56 static void
57 lunad_do_usr() {
58     // No, these are not preemptive
59     cpu_disable_interrupt();
60     
61     if (!mount_bootmedium() || !exec_initd()) {
62         fail("failed to initd");
63     }
64 }
65
66 /**
67  * @brief LunaixOS的内核进程,该进程永远为可执行。
68  *
69  * 这主要是为了保证调度器在没有进程可调度时依然有事可做。
70  *
71  * 同时,该进程也负责fork出我们的init进程。
72  *
73  */
74 void _preemptible
75 lunad_main()
76 {
77     spawn_kthread((ptr_t)init_platform);
78
79     /*
80         NOTE Kernel preemption after this point.
81
82         More specifically, it is not a real kernel preemption (as in preemption
83         happened at any point of kernel, except those marked explicitly).
84         In Lunaix, things are designed in an non-preemptive fashion, we implement 
85         kernel preemption the other way around: only selected kernel functions which,
86         of course, with great care of preemptive assumption, will goes into kernel 
87         thread (which is preemptive!)
88     */
89
90     cpu_enable_interrupt();
91     while (1)
92     {
93         cleanup_detached_threads();
94         sched_pass();
95     }
96 }
97
98 void
99 init_platform()
100 {
101     device_postboot_load();
102     invoke_init_function(on_postboot);
103
104     twifs_register_plugins();
105
106     // FIXME Re-design needed!!
107     // sdbg_init();
108     
109     assert(!spawn_process(NULL, (ptr_t)lunad_do_usr, true));
110
111     exit_thread(NULL);
112 }