Skip to content

Commit

Permalink
feat: handle data length exceeding PAGE_SIZE_4K
Browse files Browse the repository at this point in the history
  • Loading branch information
Azure-stars committed Aug 2, 2024
1 parent ff0e30e commit b36ebd1
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 18 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ user_apps:
test:
@./scripts/app_test.sh

build run justrun debug disasm clean: ax_root
build run justrun debug disasm: ax_root
@make -C $(AX_ROOT) A=$(PWD) $@

clean: ax_root
@make -C $(AX_ROOT) A=$(PWD) clean
@cargo clean

.PHONY: all ax_root build run justrun debug disasm clean
2 changes: 1 addition & 1 deletion apps/nimbos/test_cmd
Original file line number Diff line number Diff line change
@@ -1 +1 @@
test_one "LOG=error" "expect_off.out"
test_one "LOG=off" "expect_off.out"
66 changes: 50 additions & 16 deletions src/mm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,70 @@ pub fn load_user_app(app_name: &str) -> AxResult<(VirtAddr, VirtAddr, AddrSpace)
let mut uspace = axmm::new_user_aspace()?;
for segement in elf_info.segments {
debug!(
"Mapping ELF segment: {:#x?} -> {:#x?} flags: {:#x?}",
"Mapping ELF segment: [{:#x?}, {:#x?}) flags: {:#x?}",
segement.start_vaddr,
segement.start_vaddr + segement.size,
segement.flags
);
uspace.map_alloc(segement.start_vaddr, segement.size, segement.flags, true)?;

let (segement_start_paddr, _, _) = uspace
.page_table()
.query(segement.start_vaddr)
.unwrap_or_else(|_| panic!("Mapping failed for segment: {:#x?}", segement.start_vaddr));
if segement.data.is_empty() {
continue;
}

let segement_page_iter = memory_addr::PageIter4K::new(
segement.start_vaddr,
segement.start_vaddr + segement.size,
)
.expect("Failed to create page iterator");

let mut segement_data_offset = 0;

// Copy data of the segment to the physical memory
let segement_start_vaddr = phys_to_virt(segement_start_paddr).as_mut_ptr();
let segement_data_ptr = segement.data.as_ptr();
unsafe {
// Copy and align the data to the start of the page
// FIXME: Handle data length exceeding the page size
core::ptr::copy_nonoverlapping(
segement_data_ptr,
segement_start_vaddr.add(segement.offset),
segement.data.len(),
for (idx, vaddr) in segement_page_iter.enumerate() {
let (paddr, _, _) = uspace
.page_table()
.query(vaddr)
.unwrap_or_else(|_| panic!("Mapping failed for segment: {:#x?}", vaddr));

let (start_paddr, copied_size) = if idx == 0 {
// Align the start of the segment to the start of the page
(
paddr + segement.offset,
memory_addr::PAGE_SIZE_4K - segement.offset,
)
} else {
(paddr, memory_addr::PAGE_SIZE_4K)
};

debug!(
"Copying segment data: {:#x?} -> {:#x?} size: {:#x?}",
segement.start_vaddr + segement_data_offset + segement.offset,
start_paddr,
copied_size
);

unsafe {
core::ptr::copy_nonoverlapping(
segement.data.as_ptr().add(segement_data_offset),
phys_to_virt(start_paddr).as_mut_ptr(),
copied_size,
);
}

segement_data_offset += copied_size;
if segement_data_offset >= segement.data.len() {
break;
}
}
// TDOO: flush the I-cache
}

let ustack_top = uspace.end();
let ustack_vaddr = ustack_top - crate::USER_STACK_SIZE;

debug!(
"Mapping user stack: {:#x?} -> {:#x?}",
ustack_vaddr, ustack_top
);
uspace.map_alloc(
ustack_vaddr,
crate::USER_STACK_SIZE,
Expand Down

0 comments on commit b36ebd1

Please sign in to comment.