diff options
| author | Tianhao Wang <shrik3@mailbox.org> | 2024-06-05 23:01:19 +0200 |
|---|---|---|
| committer | Tianhao Wang <shrik3@mailbox.org> | 2024-06-11 15:17:14 +0200 |
| commit | 38883485c80841f15365d0502418dcc224f01d45 (patch) | |
| tree | 70f49473adccf65d7057570663c095fed8940165 /src/lib.rs | |
| parent | bfe92f51f79f367354a933b78ec2b4e9d5336119 (diff) | |
mm: use linked-list-allocator as kmalloc
I'll implement my own allocator later. Currently using linked-list
allocator [1] to manage the kernel heap (as in kmalloc, not vmalloc). It
manages the ID-mapped region (from VA 0xffff_8000_0000_0000). This
allocator is initialized to use the _largest_ physical memory block. If
the kernel image (text and data) live in this zone then skip the
occupied part.
Key difference between kmalloc and vmalloc:
- kmalloc pretty much manages the physical memory: the allocated address
are within the id-mapped region (see above) therefore the allocated
memory must also be contigous in physical memory. Such memory MUST NOT
page fault. This is prone to fragmentation, so do not use kmalloc to
allocate big objects (e.g. bigger than one 4k page).
- vmalloc manages kernel heap memory and the mapping is managed by
paging. Such memory could trigger pagefault in kernel mode.
Note that the kmalloc conflicts with the previous used stack based PMA
as they operates on the same VM zone.
References: [1] https://github.com/rust-osdev/linked-list-allocator
Signed-off-by: Tianhao Wang <shrik3@mailbox.org>
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 34 |
1 files changed, 19 insertions, 15 deletions
@@ -11,6 +11,8 @@ mod machine; mod mm; use crate::machine::key::Modifiers; mod proc; +extern crate alloc; +use alloc::vec::Vec; use arch::x86_64::interrupt; use arch::x86_64::interrupt::pic_8259; use arch::x86_64::interrupt::pic_8259::PicDeviceInt; @@ -32,38 +34,40 @@ pub extern "C" fn _entry() -> ! { io::set_attr(0x1f); io::clear_screen(); assert!(multiboot::check(), "bad multiboot info from grub!"); - let mbi = multiboot::get_mb_info().expect("bad multiboot info flags"); - let mem = unsafe { mbi.get_mem() }.unwrap(); - println!( - "[init] available memory: lower {:#X} KiB, upper:{:#X} KiB", - mem.lower(), - mem.upper() - ); - mm::init(); + // check mbi now. This will be later used to initilize the allocator + let _mbi = multiboot::get_mb_info().expect("bad multiboot info flags"); + // initialize the idt and re-program the pic. Must do this before enabling irq + // also must initialize the idt before mm, because the later may trigger page faults, which is + // fatal and we want to catch them during system initilization. interrupt::init(); - pic_8259::allow(PicDeviceInt::KEYBOARD); - interrupt::interrupt_enable(); + mm::init(); println!( "[init] kernel mapped @ {:#X} - {:#X}", - vmap_kernel_start(), - vmap_kernel_end(), + unsafe { vmap_kernel_start() }, + unsafe { vmap_kernel_end() }, ); println!( "[init] BSS mapped @ {:#X} - {:#X}", bss_start(), bss_end() ); - - // io::print_welcome(); - // busy loop query keyboard + interrupt::interrupt_enable(); + pic_8259::allow(PicDeviceInt::KEYBOARD); + let mut test_vec = Vec::<&str>::new(); + test_vec.push("hello "); + test_vec.push("world"); + for s in test_vec.iter() { + println!("{s}"); + } loop { io::KBCTL_GLOBAL.lock().fetch_key(); if let Some(k) = io::KBCTL_GLOBAL.lock().consume_key() { println! {"key: {:?}", k} } } + // test heap } pub unsafe fn _test_pf() { |
