Skip to content

Commit 0c21032

Browse files
committed
tests for LegacyFrameAllocator::construct_memory_map
This test also covers #445
1 parent 5763204 commit 0c21032

File tree

3 files changed

+249
-1
lines changed

3 files changed

+249
-1
lines changed

.github/workflows/ci.yml

+2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ jobs:
6868
- uses: r7kamura/rust-problem-matchers@v1.1.0
6969
- name: Run api tests
7070
run: cargo test -p bootloader_api
71+
- name: Run bootloader common tests
72+
run: cargo test -p bootloader-x86_64-common
7173
- name: Run integration tests
7274
run: cargo test -- --test-threads 1
7375

common/src/legacy_memory_region.rs

+246
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,249 @@ where
343343
None
344344
}
345345
}
346+
347+
#[cfg(test)]
348+
mod tests {
349+
use super::*;
350+
use bootloader_api::info::MemoryRegionKind;
351+
352+
#[derive(Copy, Clone, Debug)]
353+
struct TestMemoryRegion {
354+
start: PhysAddr,
355+
len: u64,
356+
kind: MemoryRegionKind,
357+
}
358+
359+
impl LegacyMemoryRegion for TestMemoryRegion {
360+
fn start(&self) -> PhysAddr {
361+
self.start
362+
}
363+
364+
fn len(&self) -> u64 {
365+
assert!(self.len % 4096 == 0);
366+
self.len
367+
}
368+
369+
fn kind(&self) -> MemoryRegionKind {
370+
self.kind
371+
}
372+
373+
fn usable_after_bootloader_exit(&self) -> bool {
374+
match self.kind {
375+
MemoryRegionKind::Usable => true,
376+
_ => false,
377+
}
378+
}
379+
}
380+
381+
// we need some kind of max phys memory, 4GB seems reasonable
382+
const MAX_PHYS_ADDR: u64 = 0x4000_0000;
383+
384+
fn create_single_test_region() -> Vec<TestMemoryRegion> {
385+
vec![TestMemoryRegion {
386+
start: PhysAddr::new(0),
387+
len: MAX_PHYS_ADDR,
388+
kind: MemoryRegionKind::Usable,
389+
}]
390+
}
391+
392+
#[test]
393+
fn test_kernel_and_ram_in_same_region() {
394+
let regions = create_single_test_region();
395+
let mut allocator = LegacyFrameAllocator::new(regions.into_iter());
396+
// allocate at least 1 frame
397+
allocator.allocate_frame();
398+
399+
let mut regions = [MaybeUninit::uninit(); 10];
400+
let kernel_slice_start = PhysAddr::new(0x50000);
401+
let kernel_slice_len = 0x1000;
402+
let ramdisk_slice_start = Some(PhysAddr::new(0x60000));
403+
let ramdisk_slice_len = 0x2000;
404+
405+
let kernel_regions = allocator.construct_memory_map(
406+
&mut regions,
407+
kernel_slice_start,
408+
kernel_slice_len,
409+
ramdisk_slice_start,
410+
ramdisk_slice_len,
411+
);
412+
let mut kernel_regions = kernel_regions.iter();
413+
// usable memory before the kernel
414+
assert_eq!(
415+
kernel_regions.next(),
416+
Some(&MemoryRegion {
417+
start: 0x0000,
418+
end: 0x50000,
419+
kind: MemoryRegionKind::Usable
420+
})
421+
);
422+
// kernel
423+
assert_eq!(
424+
kernel_regions.next(),
425+
Some(&MemoryRegion {
426+
start: 0x50000,
427+
end: 0x51000,
428+
kind: MemoryRegionKind::Bootloader
429+
})
430+
);
431+
// usabel memory between kernel and ramdisk
432+
assert_eq!(
433+
kernel_regions.next(),
434+
Some(&MemoryRegion {
435+
start: 0x51000,
436+
end: 0x60000,
437+
kind: MemoryRegionKind::Usable
438+
})
439+
);
440+
// ramdisk
441+
assert_eq!(
442+
kernel_regions.next(),
443+
Some(&MemoryRegion {
444+
start: 0x60000,
445+
end: 0x62000,
446+
kind: MemoryRegionKind::Bootloader
447+
})
448+
);
449+
// usabele memory after ramdisk, up until bootloader allocated memory
450+
assert_eq!(
451+
kernel_regions.next(),
452+
Some(&MemoryRegion {
453+
start: 0x62000,
454+
end: 0x10_0000,
455+
kind: MemoryRegionKind::Usable
456+
})
457+
);
458+
// bootloader allocated memory
459+
assert_eq!(
460+
kernel_regions.next(),
461+
Some(&MemoryRegion {
462+
start: 0x10_0000,
463+
end: 0x10_1000,
464+
kind: MemoryRegionKind::Bootloader
465+
})
466+
);
467+
// rest is free
468+
assert_eq!(
469+
kernel_regions.next(),
470+
Some(&MemoryRegion {
471+
start: 0x10_1000,
472+
end: MAX_PHYS_ADDR,
473+
kind: MemoryRegionKind::Usable
474+
})
475+
);
476+
assert_eq!(kernel_regions.next(), None);
477+
}
478+
479+
#[test]
480+
fn test_multiple_regions() {
481+
let regions = vec![
482+
TestMemoryRegion {
483+
start: PhysAddr::new(0),
484+
len: 0x10_0000,
485+
kind: MemoryRegionKind::Usable,
486+
},
487+
TestMemoryRegion {
488+
start: PhysAddr::new(0x10_0000),
489+
len: 0x5000,
490+
kind: MemoryRegionKind::UnknownBios(0),
491+
},
492+
TestMemoryRegion {
493+
start: PhysAddr::new(0x10_5000),
494+
len: MAX_PHYS_ADDR - 0x10_5000,
495+
kind: MemoryRegionKind::Usable,
496+
},
497+
];
498+
let mut allocator = LegacyFrameAllocator::new(regions.into_iter());
499+
// allocate at least 1 frame
500+
allocator.allocate_frame();
501+
502+
let mut regions = [MaybeUninit::uninit(); 10];
503+
let kernel_slice_start = PhysAddr::new(0x50000);
504+
let kernel_slice_len = 0x1000;
505+
let ramdisk_slice_start = Some(PhysAddr::new(0x60000));
506+
let ramdisk_slice_len = 0x2000;
507+
508+
let kernel_regions = allocator.construct_memory_map(
509+
&mut regions,
510+
kernel_slice_start,
511+
kernel_slice_len,
512+
ramdisk_slice_start,
513+
ramdisk_slice_len,
514+
);
515+
let mut kernel_regions = kernel_regions.iter();
516+
517+
// usable memory before the kernel
518+
assert_eq!(
519+
kernel_regions.next(),
520+
Some(&MemoryRegion {
521+
start: 0x0000,
522+
end: 0x50000,
523+
kind: MemoryRegionKind::Usable
524+
})
525+
);
526+
// kernel
527+
assert_eq!(
528+
kernel_regions.next(),
529+
Some(&MemoryRegion {
530+
start: 0x50000,
531+
end: 0x51000,
532+
kind: MemoryRegionKind::Bootloader
533+
})
534+
);
535+
// usabel memory between kernel and ramdisk
536+
assert_eq!(
537+
kernel_regions.next(),
538+
Some(&MemoryRegion {
539+
start: 0x51000,
540+
end: 0x60000,
541+
kind: MemoryRegionKind::Usable
542+
})
543+
);
544+
// ramdisk
545+
assert_eq!(
546+
kernel_regions.next(),
547+
Some(&MemoryRegion {
548+
start: 0x60000,
549+
end: 0x62000,
550+
kind: MemoryRegionKind::Bootloader
551+
})
552+
);
553+
// usabele memory after ramdisk, up until bootloader allocated memory
554+
assert_eq!(
555+
kernel_regions.next(),
556+
Some(&MemoryRegion {
557+
start: 0x62000,
558+
end: 0x10_0000,
559+
kind: MemoryRegionKind::Usable
560+
})
561+
);
562+
// the unknown bios region
563+
assert_eq!(
564+
kernel_regions.next(),
565+
Some(&MemoryRegion {
566+
start: 0x10_0000,
567+
end: 0x10_5000,
568+
kind: MemoryRegionKind::UnknownBios(0)
569+
})
570+
);
571+
// bootloader allocated memory, this gets pushed back by the bios region
572+
assert_eq!(
573+
kernel_regions.next(),
574+
Some(&MemoryRegion {
575+
start: 0x10_5000,
576+
end: 0x10_6000,
577+
kind: MemoryRegionKind::Bootloader
578+
})
579+
);
580+
// rest is free
581+
assert_eq!(
582+
kernel_regions.next(),
583+
Some(&MemoryRegion {
584+
start: 0x10_6000,
585+
end: MAX_PHYS_ADDR,
586+
kind: MemoryRegionKind::Usable
587+
})
588+
);
589+
assert_eq!(kernel_regions.next(), None);
590+
}
591+
}

common/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![no_std]
1+
#![cfg_attr(not(test), no_std)]
22
#![feature(step_trait)]
33
#![deny(unsafe_op_in_unsafe_fn)]
44

0 commit comments

Comments
 (0)