Ejemplo n.º 1
0
Archivo: mm_phys.c Proyecto: PtxDK/OSM
void physmem_init(void *boot_info)
{
  multiboot_info_t *mb_info = (multiboot_info_t*)boot_info;
  uint64_t *mem_ptr = (uint64_t*)(uint64_t)mb_info->memory_map_addr;
  uint64_t Itr = 0, last_address = 0;

  /* Setup Memory Stuff */
  highest_page = 0;
  memory_size = mb_info->memory_high;
  memory_size += mb_info->memory_low;
  total_blocks = (memory_size * 1024) / PAGE_SIZE;
  used_blocks = total_blocks;
  bitmap_size = total_blocks / PMM_BLOCKS_PER_BYTE;
  _mem_bitmap = (uint64_t*)stalloc(bitmap_size);
  physmem_lock = (spinlock_t*)stalloc(sizeof(spinlock_t));
  spinlock_reset(physmem_lock);

  /* Set all memory as used, and use memory map to set free */
  memoryset(_mem_bitmap, 0xF, bitmap_size);

  /* Physical Page Bitmap */
  kprintf("Memory size: %u Kb\n", (uint32_t)memory_size);

  /* Go through regions */
  for(Itr = (uint64_t)mem_ptr;
      Itr < ((uint64_t)mem_ptr + mb_info->memory_map_length);
      )
    {
      /* Get next member */
      mem_region_t *mem_region = (mem_region_t*)Itr;

      /* Output */
      //kprintf("Memory Region: Address 0x%xL, length 0x%xL, Type %u\n",
      //        mem_region->base_address, mem_region->length, mem_region->Type);

      /* Is it free? */
      if(mem_region->type == MEMTYPE_FREE)
        physmem_freeregion(mem_region->base_address,
                           mem_region->length);

      /* Advance by one structure */
      Itr += sizeof(mem_region_t);
    }

  /* Mark all memory up to the static allocation point as used */
  last_address = (physaddr_t)stalloc(1);
  stalloc_disable();

  for(Itr = physmem_allocblock(); Itr < last_address;)
    Itr = physmem_allocblock();

  /* Debug*/
  kprintf("New memory allocation starts at 0x%xl\n", Itr);
}
Ejemplo n.º 2
0
Archivo: process.c Proyecto: PtxDK/OSM
void* syscall_memlimit(void* new_end){
  uint32_t phys_page;
  interrupt_status_t intr_status;
  
  intr_status = _interrupt_disable();
  spinlock_acquire(&process_table_slock);
  
  process_control_block_t *curr_proc = process_get_current_process_entry();
  // checks if the new_end is NULL
  if (new_end == NULL){
    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    return (void*)curr_proc->heap_end;
  }
  // checks if we are trying to shrink the memory, if so we error
  // and return NULL
  if ((uint32_t)new_end < curr_proc->heap_end){
    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    return NULL;
  }
  // loop where we alloc the physical and the virtual memoery, we also check
  // if we have enough physical memory.
  for (uint32_t i = (curr_proc->heap_end / PAGE_SIZE +1);
       i <= ((uint32_t)new_end / PAGE_SIZE);i++){
    // we allocate some physical memory.
    phys_page = physmem_allocblock();
    //check if we got enough physical memory, if we do not we error
    if (phys_page == 0){
      spinlock_release(&process_table_slock);
      _interrupt_set_state(intr_status);
      return NULL;
    }
    // maps the virtual memory
    vm_map(thread_get_current_thread_entry()->pagetable,
           phys_page, i * PAGE_SIZE, 1);
  }
  // if nothing fails we at last set heap_end to  new_end
  curr_proc->heap_end = (uint32_t)new_end;
  
  spinlock_release(&process_table_slock);
  _interrupt_set_state(intr_status);
  return new_end;
}
Ejemplo n.º 3
0
/* Return non-zero on error. */
int setup_new_process(TID_t thread,
                      const char *executable, const char **argv_src,
                      virtaddr_t *entry_point, virtaddr_t *stack_top)
{
  pagetable_t *pagetable;
  elf_info_t elf;
  openfile_t file;
  uintptr_t phys_page;
  int i, res;
  thread_table_t *thread_entry = thread_get_thread_entry(thread);

  int argc = 1;
  virtaddr_t argv_begin;
  virtaddr_t argv_dst;
  int argv_elem_size;
  virtaddr_t argv_elem_dst;

  file = vfs_open((char *)executable);

  /* Make sure the file existed and was a valid ELF file */
  if (file < 0) {
    return -1;
  }

  res = elf_parse_header(&elf, file);
  if (res < 0) {
    return -1;
  }

  /* Trivial and naive sanity check for entry point: */
  if (elf.entry_point < PAGE_SIZE) {
    return -1;
  }

  *entry_point = elf.entry_point;

  pagetable = vm_create_pagetable(thread);

  thread_entry->pagetable = pagetable;

  /* Allocate and map stack */
  for(i = 0; i < CONFIG_USERLAND_STACK_SIZE; i++) {
    phys_page = physmem_allocblock();
    KERNEL_ASSERT(phys_page != 0);
    /* Zero the page */
    memoryset((void*)ADDR_PHYS_TO_KERNEL(phys_page), 0, PAGE_SIZE);
    vm_map(pagetable, phys_page,
           (USERLAND_STACK_TOP & PAGE_SIZE_MASK) - i*PAGE_SIZE, 1);
  }

  /* Allocate and map pages for the segments. We assume that
     segments begin at page boundary. (The linker script in tests
     directory creates this kind of segments) */
  for(i = 0; i < (int)elf.ro_pages; i++) {
    int left_to_read = elf.ro_size - i*PAGE_SIZE;
    phys_page = physmem_allocblock();
    KERNEL_ASSERT(phys_page != 0);
    /* Zero the page */
    memoryset((void*)ADDR_PHYS_TO_KERNEL(phys_page), 0, PAGE_SIZE);
    /* Fill the page from ro segment */
    if (left_to_read > 0) {
      KERNEL_ASSERT(vfs_seek(file, elf.ro_location + i*PAGE_SIZE) == VFS_OK);
      KERNEL_ASSERT(vfs_read(file, (void*)ADDR_PHYS_TO_KERNEL(phys_page),
                             MIN(PAGE_SIZE, left_to_read))
                    == (int) MIN(PAGE_SIZE, left_to_read));
    }
    vm_map(pagetable, phys_page,
           elf.ro_vaddr + i*PAGE_SIZE, 0);
  }

  for(i = 0; i < (int)elf.rw_pages; i++) {
    int left_to_read = elf.rw_size - i*PAGE_SIZE;
    phys_page = physmem_allocblock();
    KERNEL_ASSERT(phys_page != 0);
    /* Zero the page */
    memoryset((void*)ADDR_PHYS_TO_KERNEL(phys_page), 0, PAGE_SIZE);
    /* Fill the page from rw segment */
    if (left_to_read > 0) {
      KERNEL_ASSERT(vfs_seek(file, elf.rw_location + i*PAGE_SIZE) == VFS_OK);
      KERNEL_ASSERT(vfs_read(file, (void*)ADDR_PHYS_TO_KERNEL(phys_page),
                             MIN(PAGE_SIZE, left_to_read))
                    == (int) MIN(PAGE_SIZE, left_to_read));
    }
    vm_map(pagetable, phys_page,
           elf.rw_vaddr + i*PAGE_SIZE, 1);
  }

  /* Set up argc and argv on the stack. */

  /* Start by preparing ancillary information for the new process argv. */
  if (argv_src != NULL)
    for (i = 0; argv_src[i] != NULL; i++) {
      argc++;
    }

  argv_begin = USERLAND_STACK_TOP - (argc * sizeof(virtaddr_t));
  argv_dst = argv_begin;

  /* Prepare for copying executable. */
  argv_elem_size = strlen(executable) + 1;
  argv_elem_dst = argv_dst - wordpad(argv_elem_size);

  /* Copy executable to argv[0] location. */
  vm_memwrite(pagetable,
              argv_elem_size,
              argv_elem_dst,
              executable);
  /* Set argv[i] */
  vm_memwrite(pagetable,
              sizeof(virtaddr_t),
              argv_dst,
              &argv_elem_dst);

  /* Move argv_dst to &argv[1]. */
  argv_dst += sizeof(virtaddr_t);

  if (argv_src != NULL) {
    for (i = 0; argv_src[i] != NULL; i++) {
      /* Compute the size of argv[i+1] */
      argv_elem_size = strlen(argv_src[i]) + 1;
      argv_elem_dst -= wordpad(argv_elem_size);

      /* Write the 'i+1'th element of argv */
      vm_memwrite(pagetable,
                  argv_elem_size,
                  argv_elem_dst,
                  argv_src[i]);

      /* Write argv[i+1] */
      vm_memwrite(pagetable,
                  sizeof(virtaddr_t),
                  argv_dst,
                  &argv_elem_dst);

      /* Move argv_dst to next element of argv. */
      argv_dst += sizeof(virtaddr_t);
    }
  }

  /* Write argc to the stack. */
  vm_memwrite(pagetable,
              sizeof(int),
              argv_elem_dst - sizeof(int),
              &argc);
  /* Write argv to the stack. */
  vm_memwrite(pagetable,
              sizeof(virtaddr_t),
              argv_elem_dst - sizeof(int) - sizeof(virtaddr_t),
              &argv_begin);

  /* Stack pointer points at argv. */
  *stack_top = argv_elem_dst - sizeof(int) - sizeof(virtaddr_t);

  return 0;
}