Day-2
Paging
We delve into paging.
Example
1 | /// Physical address for pflash#1 |
PFlash is the simulation of flash memory of qemu. When qemu boot, it will automatically load file to fixed MMIO, and can be directly accessed.
Paging: feature = ["paging"] is the way to evoke virtual memory management tu support MMIO. Located in axruntime.
The workflow would be:
- qemu fdt: from
0x0c00_0000to0x3000_0000. Construct the space of device. - SBI: from
0x8000_0000to0x8020_0000. RISC-V Supervisor Binary Interface, it construct a interface for programming language to manipulate device level things. - Kernel Image: from
0x8020_0000._skernelcontains S-level things like static data, code etc…_ekernelis user thing.
1 |
|
Each entry of page table will map 1G(0x4000_0000) memory. From 0x8000_0000 to 0xc0000_0000 at pgd_idx = 2 to 0xffff_ffc0_8000_0000 to 0xffff_ffc0_c000_0000 at pgd_idx = 102. This will map to a bigger range.
Task
Example
1 | let worker = thread::spawn(move || { |
Each task will be in concurrency and dispatched by strategy. If it’s blocked, it will be moved to wait_queue to wait. If it’s ready, it will be moved to run_queue which is scheduler to be dispatched.
Message Communication
Example
1 | let q1 = Arc::new(SpinNoIrq::new(VecDeque::new())); |
Cooperative Scheduling: Each tasks kindly yield themselves or exit otherwise it will block everyone because the power of CPU occupation is ownned by each tasks.
Preemptive Scheduling: Each tasks will be automatically suspended by external condition: No lock, no device access; inner condition: run out of current time slice. We can use a disable_count to record this, even for multiple condition restriction, we can sum them up.
1 | axhal::irq::register_handler(TIMER_IRQ_NUM, || { |
on_timer_tick will be trigger in time slice. When time ticker ticks, run_queue will check and suspend task if possible.
We can make it more dynamic. Which means each task has priority and during the implementation of cpu, each task has a vruntime to be dynamically adjusted by init_vruntime + (delta/weight(nice)) where delta and nice are dynamic adjustment number. delta will be incremented by timer, weight(nice) is actually the priority of the task. We ensure that task with lowest vruntime will be placed at top.