Skip to content

Commit 3d99cfc

Browse files
committed
Zero bss sections (and similar)
1 parent 1ef0365 commit 3d99cfc

File tree

1 file changed

+30
-5
lines changed

1 file changed

+30
-5
lines changed

src/page_table.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use frame_allocator::FrameAllocator;
2-
use x86_64::{PhysAddr, VirtAddr};
2+
use x86_64::{PhysAddr, VirtAddr, align_up};
33
use x86_64::structures::paging::{PAGE_SIZE, PageTable, PageTableFlags, PageTableEntry, Page, PhysFrame};
44
use usize_conversions::usize_from;
55
use xmas_elf;
@@ -38,14 +38,19 @@ pub(crate) fn identity_map(frame: PhysFrame, flags: PageTableFlags, p4: &mut Pag
3838
pub(crate) fn map_segment(kernel_start: PhysAddr, program_header: ProgramHeader, p4: &mut PageTable,
3939
frame_allocator: &mut FrameAllocator)
4040
{
41+
unsafe fn zero_frame(frame: &PhysFrame) {
42+
let frame_ptr = frame.start_address().as_u64() as *mut [u8; PAGE_SIZE as usize];
43+
*frame_ptr = [0; PAGE_SIZE as usize];
44+
}
45+
4146
let typ = program_header.get_type().unwrap();
4247
match typ {
4348
program::Type::Load => {
49+
let mem_size = program_header.mem_size();
50+
let file_size = program_header.file_size();
4451
let file_offset = program_header.offset();
4552
let phys_start_addr = kernel_start + file_offset;
46-
let size = program_header.mem_size();
4753
let virt_start_addr = VirtAddr::new(program_header.virtual_addr());
48-
let virt_end_addr = virt_start_addr + size;
4954

5055
let flags = program_header.flags();
5156
let mut page_table_flags = PageTableFlags::PRESENT;
@@ -54,10 +59,30 @@ pub(crate) fn map_segment(kernel_start: PhysAddr, program_header: ProgramHeader,
5459

5560
for offset in (0..).step_by(usize_from(PAGE_SIZE)) {
5661
let page = Page::containing_address(virt_start_addr + offset);
57-
let frame = PhysFrame::containing_address(phys_start_addr + offset);
58-
if page.start_address() >= virt_end_addr {
62+
let frame;
63+
if offset >= mem_size {
5964
break
6065
}
66+
if offset >= file_size {
67+
// map to zeroed frame
68+
frame = frame_allocator.allocate_frame();
69+
unsafe { zero_frame(&frame) };
70+
} else if align_up(offset, u64::from(PAGE_SIZE)) - 1 >= file_size {
71+
// part of the page should be zeroed
72+
frame = frame_allocator.allocate_frame();
73+
unsafe { zero_frame(&frame) };
74+
// copy data from kernel image
75+
let data_frame_start = PhysFrame::containing_address(phys_start_addr + offset);
76+
let data_ptr = data_frame_start.start_address().as_u64() as *const u8;
77+
let frame_ptr = frame.start_address().as_u64() as *mut u8;
78+
for i in offset..file_size {
79+
let i = i as isize;
80+
unsafe { frame_ptr.offset(i).write(data_ptr.offset(i).read()) };
81+
}
82+
} else {
83+
// map to part of kernel binary
84+
frame = PhysFrame::containing_address(phys_start_addr + offset);
85+
}
6186
map_page(page, frame, page_table_flags, p4, frame_allocator);
6287
}
6388
},

0 commit comments

Comments
 (0)