optimize the menuconfig redrawing
[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     const char* argv[] = { "/mnt/lunaix-os/usr/bin/init", 0 };
45     const char* envp[] = { 0 };
46
47     if ((errno = exec_kexecve(argv[0], argv, envp))) {
48         goto fail;
49     }
50
51     fail("should not reach");
52
53 fail:
54     ERROR("fail to load initd. (%d)", errno);
55     return 0;
56 }
57
58 static void
59 lunad_do_usr() {
60     // No, these are not preemptive
61     no_preemption();
62
63     if (!mount_bootmedium() || !exec_initd()) {
64         fail("failed to initd");
65     }
66 }
67
68 /**
69  * @brief LunaixOS的内核进程,该进程永远为可执行。
70  *
71  * 这主要是为了保证调度器在没有进程可调度时依然有事可做。
72  *
73  * 同时,该进程也负责fork出我们的init进程。
74  *
75  */
76 void _preemptible
77 lunad_main()
78 {
79     spawn_kthread((ptr_t)init_platform);
80
81     /*
82         NOTE Kernel preemption after this point.
83
84         More specifically, it is not a real kernel preemption (as in preemption
85         happened at any point of kernel, except those marked explicitly).
86         In Lunaix, things are designed in an non-preemptive fashion, we implement 
87         kernel preemption the other way around: only selected kernel functions which,
88         of course, with great care of preemptive assumption, will goes into kernel 
89         thread (which is preemptive!)
90     */
91
92     set_preemption();
93     while (1)
94     {
95         cleanup_detached_threads();
96         yield_current();
97     }
98 }
99
100 void
101 init_platform()
102 {
103     device_postboot_load();
104     invoke_init_function(on_postboot);
105
106     twifs_register_plugins();
107
108     // FIXME Re-design needed!!
109     // sdbg_init();
110     
111     assert(!spawn_process(NULL, (ptr_t)lunad_do_usr, true));
112
113     exit_thread(NULL);
114 }