1use core::sync::atomic::Ordering;
4
5use alloc::sync::Arc;
6use riscv::register::sscratch;
7
8use crate::{
9 arch::{intr, mm::vaddr_to_paddr, platform, timer, trap},
10 earlyprintln,
11 ipc::{SignalHandlerTable, SignalPending},
12 kernel::{
13 FsStruct, SCHEDULER, Scheduler, TASK_MANAGER, TaskManagerTrait, TaskStruct, current_cpu,
14 current_memory_space, current_task, kernel_execve, kthread_spawn, kworker,
15 sleep_task_with_block, time, yield_task,
16 },
17 mm::{
18 self,
19 frame_allocator::{alloc_contig_frames, alloc_frame},
20 },
21 pr_err, pr_info, println,
22 sync::SpinLock,
23 test::run_early_tests,
24 uapi::{
25 resource::{INIT_RLIMITS, RlimitStruct},
26 signal::SignalFlags,
27 uts_namespace::UtsNamespace,
28 },
29 vfs::{create_stdio_files, fd_table, get_root_dentry},
30};
31
32pub fn rest_init() {
35 let tid = TASK_MANAGER.lock().allocate_tid();
36 let kstack_tracker = alloc_contig_frames(4).expect("kthread_spawn: failed to alloc kstack");
37 let trap_frame_tracker = alloc_frame().expect("kthread_spawn: failed to alloc trap_frame");
38 let fd_table = fd_table::FDTable::new();
39 let (stdin, stdout, stderr) = create_stdio_files();
40 fd_table
41 .install_at(0, stdin)
42 .expect("Failed to install stdin");
43 fd_table
44 .install_at(1, stdout)
45 .expect("Failed to install stdout");
46 fd_table
47 .install_at(2, stderr)
48 .expect("Failed to install stderr");
49 let cwd = get_root_dentry().ok();
50 let root = cwd.clone();
51 let fs = Arc::new(SpinLock::new(FsStruct::new(cwd, root)));
52 let mut task = TaskStruct::ktask_create(
53 tid,
54 tid,
55 0,
56 TaskStruct::empty_children(),
57 kstack_tracker,
58 trap_frame_tracker,
59 Arc::new(SpinLock::new(SignalHandlerTable::new())),
60 SignalFlags::empty(),
61 Arc::new(SpinLock::new(SignalPending::empty())),
62 Arc::new(SpinLock::new(UtsNamespace::default())),
63 Arc::new(SpinLock::new(RlimitStruct::new(INIT_RLIMITS))),
64 Arc::new(fd_table),
65 fs,
66 ); let tf = task.trap_frame_ptr.load(Ordering::SeqCst);
69 unsafe {
71 (*tf).set_kernel_trap_frame(init as usize, 0, task.kstack_base);
72 }
73
74 let ra = task.context.ra;
75 let sp = task.context.sp;
76 let ptr = task.trap_frame_ptr.load(Ordering::SeqCst);
77 task.memory_space = Some(current_memory_space());
79 let task = task.into_shared();
80 unsafe {
81 sscratch::write(ptr as usize);
82 }
83 TASK_MANAGER.lock().add_task(task.clone());
84 current_cpu().lock().switch_task(task);
85
86 unsafe {
89 core::arch::asm!(
90 "mv sp, {sp}",
91 "jr {ra}",
92 sp = in(reg) sp,
93 ra = in(reg) ra,
94 options(noreturn)
95 );
96 }
97}
98
99fn init() {
105 super::trap::init();
106
107 create_kthreadd();
108
109 if let Err(e) = crate::fs::init_ext4_from_block_device() {
112 pr_err!(
113 "[Init] Warning: Failed to initialize Ext4 filesystem: {:?}",
114 e
115 );
116 pr_info!("[Init] Continuing without filesystem...");
117 }
118
119 kernel_execve("/sbin/init", &["/sbin/init"], &[]);
127}
128
129fn kthreadd() {
133 kthread_spawn(kworker);
134 loop {
135 sleep_task_with_block(current_task(), true);
137 yield_task();
138 }
139}
140
141fn create_kthreadd() {
143 let tid = TASK_MANAGER.lock().allocate_tid();
144 let kstack_tracker = alloc_contig_frames(4).expect("kthread_spawn: failed to alloc kstack");
145 let trap_frame_tracker = alloc_frame().expect("kthread_spawn: failed to alloc trap_frame");
146 let (uts, rlimit, fd_table, fs) = {
147 let task = current_task();
148 let t = task.lock();
149 (
150 t.uts_namespace.clone(),
151 t.rlimit.clone(),
152 t.fd_table.clone_table(),
153 t.fs.lock().clone(),
154 )
155 };
156 let task = TaskStruct::ktask_create(
157 tid,
158 tid,
159 0,
160 TaskStruct::empty_children(),
161 kstack_tracker,
162 trap_frame_tracker,
163 Arc::new(SpinLock::new(SignalHandlerTable::new())),
164 SignalFlags::empty(),
165 Arc::new(SpinLock::new(SignalPending::empty())),
166 uts,
167 rlimit,
168 Arc::new(fd_table),
169 Arc::new(SpinLock::new(fs)),
170 ); let tf = task.trap_frame_ptr.load(Ordering::SeqCst);
173 unsafe {
175 (*tf).set_kernel_trap_frame(kthreadd as usize, 0, task.kstack_base);
176 }
177 let task = task.into_shared();
178 TASK_MANAGER.lock().add_task(task.clone());
179 SCHEDULER.lock().add_task(task);
180}
181
182pub fn main(hartid: usize) {
183 clear_bss();
184
185 run_early_tests();
186
187 earlyprintln!("[Boot] Hello, world!");
188 earlyprintln!("[Boot] RISC-V Hart {} is up!", hartid);
189
190 mm::init();
191
192 #[cfg(test)]
193 crate::test_main();
194
195 trap::init_boot_trap();
197 platform::init();
198 time::init();
199 timer::init();
200 unsafe { intr::enable_interrupts() };
201
202 rest_init();
203}
204
205fn clear_bss() {
209 unsafe extern "C" {
210 fn sbss();
211 fn ebss();
212 }
213
214 let sbss_paddr = unsafe { vaddr_to_paddr(sbss as usize) };
215 let ebss_paddr = unsafe { vaddr_to_paddr(ebss as usize) };
216
217 (sbss_paddr..ebss_paddr).for_each(|a| unsafe {
218 let va = crate::arch::mm::paddr_to_vaddr(a);
220 (va as *mut u8).write_volatile(0)
221 });
222}
223
224