示例#1
0
/* Initialize pages for initial process (user pages) */
void set_user_pages( struct task_struct *task )
{
 int pag; 
 int new_ph_pag;
 page_table_entry * process_PT =  get_PT(task);


  /* CODE */
  for (pag=0;pag<NUM_PAG_CODE;pag++){
	new_ph_pag=alloc_frame();
  	process_PT[PAG_LOG_INIT_CODE_P0+pag].entry = 0;
  	process_PT[PAG_LOG_INIT_CODE_P0+pag].bits.pbase_addr = new_ph_pag;
  	process_PT[PAG_LOG_INIT_CODE_P0+pag].bits.user = 1;
  	process_PT[PAG_LOG_INIT_CODE_P0+pag].bits.present = 1;
  }
  
  /* DATA */ 
  for (pag=0;pag<NUM_PAG_DATA;pag++){
	new_ph_pag=alloc_frame();
  	process_PT[PAG_LOG_INIT_DATA_P0+pag].entry = 0;
  	process_PT[PAG_LOG_INIT_DATA_P0+pag].bits.pbase_addr = new_ph_pag;
  	process_PT[PAG_LOG_INIT_DATA_P0+pag].bits.user = 1;
  	process_PT[PAG_LOG_INIT_DATA_P0+pag].bits.rw = 1;
  	process_PT[PAG_LOG_INIT_DATA_P0+pag].bits.present = 1;
  }
}
示例#2
0
void initialize_paging(uint32_t memsize)
{
	nframes = memsize / 4;
	frames = (uint32_t *)kmalloc(INDEX_FROM_BIT(nframes));
	uintptr_t pg;

	assert(frames != NULL);

	memset(frames, 0, INDEX_FROM_BIT(nframes));

	uintptr_t physical;
	kernel_directory = (page_directory_t *)kmalloc_ap(sizeof(page_directory_t), &physical);
	memset(kernel_directory, 0, sizeof(page_directory_t));
	current_directory = kernel_directory;

#if 1
	get_page(0,1,kernel_directory)->present = 0;
	set_frame(0);

	for(uintptr_t i = 0x1000; i < placement_address+0x3000; i += 0x1000)
#else
	for(uintptr_t i = 0x0; i < placement_address+0x3000; i += 0x1000)
#endif
	{
		direct_frame( get_page(i, 1, kernel_directory), 1, 0, i);
	}
	
	kernel_directory->physical_addr = (uintptr_t)kernel_directory->tables_physical;

	uintptr_t heap_start = KERNEL_HEAP_START;

	if(heap_start <= placement_address + 0x3000)
	{
		heap_start = placement_address + 0x100000;
	}
	
	for (uintptr_t i = placement_address + 0x3000; i < heap_start; i += 0x1000)
	{
		alloc_frame(get_page(i, 1, kernel_directory), 1, 0);
	}

	for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000)
	{
		get_page(i, 1, kernel_directory);
	}

	for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000)
	{
		alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
	}
	
	register_isr_handler(13, general_protection_fault);
	register_isr_handler(14, page_fault);	

	switch_page_directory(kernel_directory);

	kernel_heap = create_heap(heap_start, heap_start + KERNEL_HEAP_INIT, KERNEL_HEAP_END, 0, 0);
	//kernel_heap = create_heap(heap_start, KERNEL_HEAP_END, KERNEL_HEAP_END, 0, 0);
}
示例#3
0
/* Creates a new kernel thread named NAME with the given initial
   PRIORITY, which executes FUNCTION passing AUX as the argument,
   and adds it to the ready queue.  Returns the thread identifier
   for the new thread, or TID_ERROR if creation fails.

   If thread_start() has been called, then the new thread may be
   scheduled before thread_create() returns.  It could even exit
   before thread_create() returns.  Contrariwise, the original
   thread may run for any amount of time before the new thread is
   scheduled.  Use a semaphore or some other form of
   synchronization if you need to ensure ordering.

   The code provided sets the new thread's `priority' member to
   PRIORITY, but no actual priority scheduling is implemented.
   Priority scheduling is the goal of Problem 1-3. */
tid_t
thread_create (const char *name, int priority,
               thread_func *function, void *aux) 
{
  struct thread *t;
  struct kernel_thread_frame *kf;
  struct switch_entry_frame *ef;
  struct switch_threads_frame *sf;
  tid_t tid;
  enum intr_level old_level;

  ASSERT (function != NULL);

  /* Allocate thread. */
  t = palloc_get_page (PAL_ZERO);
  if (t == NULL)
    return TID_ERROR;

  /* Initialize thread. */
  init_thread (t, name, priority);
  tid = t->tid = allocate_tid ();

  /* Prepare thread for first run by initializing its stack.
     Do this atomically so intermediate values for the 'stack' 
     member cannot be observed. */
  old_level = intr_disable ();

  /* Stack frame for kernel_thread(). */
  kf = alloc_frame (t, sizeof *kf);
  kf->eip = NULL;
  kf->function = function;
  kf->aux = aux;

  /* Stack frame for switch_entry(). */
  ef = alloc_frame (t, sizeof *ef);
  ef->eip = (void (*) (void)) kernel_thread;

  /* Stack frame for switch_threads(). */
  sf = alloc_frame (t, sizeof *sf);
  sf->eip = switch_entry;
  sf->ebp = 0;

  intr_set_level (old_level);

  /* Add to run queue. */
  thread_unblock (t);

  //we need to call thread yield now to check if this thread
  //has the highest priority
  thread_yield();

  return tid;
}
示例#4
0
void init_paging()
{
	size_t sz;
	uint32_t i;
	uint32_t mem_end_page;

	DPRINTK("paging...\t\t");

	mem_end_page = 0x1000000;
	nframes = mem_end_page / PAGE_SIZ;

	sz = INDEX_FROM_BIT(nframes);
	frames = (uint32_t *)kmalloc(sz);
	memset(frames, 0, sz);

	kernel_directory = (struct page_directory *)
		kmalloc_a(sizeof(struct page_directory));
	memset(kernel_directory, 0, sizeof(struct page_directory));

	// don't do this...
	current_directory = kernel_directory;

	// do this instead...
	kernel_directory->physical_addr = (uint32_t)kernel_directory->tables_physical;

	for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZ)
		get_page(i, 1, kernel_directory);

	i = 0;
	while (i < placement_addr + PAGE_SIZ) {
		alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
		i += PAGE_SIZ;
	}

	for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZ)
		alloc_frame(get_page(i, 1, kernel_directory), 0, 0);

	// register_interrupt_handler(14, page_fault);

	switch_page_directory(kernel_directory);
	enable_paging();

	kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0);

	current_directory = clone_directory(kernel_directory);
        switch_page_directory(current_directory);

	DPRINTK("done!\n");
}
示例#5
0
文件: kheap.c 项目: itravers/PanicOS
/* Expands the size of a given heap. */
static void expand(u32int new_size, heap_t *heap){
  //printf("\nexpanding kheap to 0x%x \n", new_size);
  // Sanity check. Make sure the expanded size is available in the heap area.
  ASSERT(new_size > heap->end_address - heap->start_address);

  // Get the nearest following page boundary.
  if ((new_size&0xFFFFF000) != 0){
    new_size &= 0xFFFFF000;
    new_size += 0x1000;
  }

  // Make sure we are not overreaching ourselves.
  ASSERT(heap->start_address+new_size <= heap->max_address);

  // This should always be on a page boundary.
  u32int old_size = heap->end_address-heap->start_address;

  u32int i = old_size;
  while (i < new_size){
    alloc_frame( get_page(heap->start_address+i, 1, kernel_directory),
                 (heap->supervisor)?1:0, (heap->readonly)?0:1);
    i += 0x1000 /* page size */;
  }
  heap->end_address = heap->start_address+new_size;
}
示例#6
0
文件: elf.c 项目: codyd51/axle
//map pages for bss segment pointed to by shdr
//stores program break (end of .bss segment) in prog_break
//stored start of .bss segment in bss_loc
static void alloc_bss(page_directory_t* new_dir, elf_s_header* shdr, int* prog_break, int* bss_loc) {
	printf("ELF .bss mapped @ %x - %x\n", shdr->addr, shdr->addr + shdr->size);
	for (uint32_t i = 0; i <= shdr->size + PAGE_SIZE; i += PAGE_SIZE) {
		page_t* page = get_page(shdr->addr + i, 1, new_dir);
		if (!alloc_frame(page, 0, 1)) {
			printf_err(".bss %x wasn't alloc'd", shdr->addr + i);
		}

		char* pagebuf = kmalloc_a(PAGE_SIZE);
		//zero out .bss
		memset(pagebuf, 0, PAGE_SIZE);

		page_t* local_page = get_page((uint32_t)pagebuf, 1, page_dir_current());
		ASSERT(local_page, "elf_load_segment couldn't find page for pagebuf");

		extern void copy_page_physical(uint32_t page, uint32_t dest);
		copy_page_physical(local_page->frame * PAGE_SIZE, page->frame * PAGE_SIZE);

		//now that the buffer has been copied, we can safely free the buffer
		kfree(pagebuf);
	}

	//set program break to .bss segment
	*prog_break = shdr->addr + shdr->size;
	*bss_loc = shdr->addr;
}
示例#7
0
TilemAnimation * tilem_animation_new(int display_width, int display_height)
{
	TilemAnimation *anim;
	TilemAnimFrame *dummy_frame;

	g_return_val_if_fail(display_width > 0, NULL);
	g_return_val_if_fail(display_height > 0, NULL);

	anim = g_object_new(TILEM_TYPE_ANIMATION, NULL);
	anim->display_width = display_width;
	anim->display_height = display_height;
	anim->frame_rowstride = (display_width + 7) & ~7;
	anim->frame_size = anim->frame_rowstride * display_height;

	anim->image_width = display_width;
	anim->image_height = display_height;
	anim->speed = 1.0;
	anim->time_stretch = 1.0;

	anim->temp_buffer = tilem_lcd_buffer_new();
	anim->palette = tilem_color_palette_new(255, 255, 255, 0, 0, 0, GAMMA);

	dummy_frame = alloc_frame(anim->frame_size);
	dummy_frame->duration = 0;
	dummy_frame->contrast = 0;
	anim->start = anim->end = dummy_frame;

	return anim;
}
示例#8
0
文件: kheap.cpp 项目: zerotri/Amarant
static void expand(uint32_t new_size, heap_t *heap)
{
    // Sanity check.
    if(new_size > heap->end_address - heap->start_address)
		return;

    // Get the nearest following page boundary.
    if ((new_size&0xFFFFF000) != 0)
    {
        new_size &= 0xFFFFF000;
        new_size += 0x1000;
    }

    // Make sure we are not overreaching ourselves.
    if(heap->start_address+new_size <= heap->max_address)
		return;

    // This should always be on a page boundary.
    uint32_t old_size = heap->end_address-heap->start_address;

    uint32_t i = old_size;
    while (i < new_size)
    {
        alloc_frame( get_page(heap->start_address+i, 1, kernel_directory),
                     (heap->supervisor)?1:0, (heap->readonly)?0:1);
        i += 0x1000 /* page size */;
    }
    heap->end_address = heap->start_address+new_size;
}
示例#9
0
static void expand(uint32_t new_size, heap_t *heap, int size) {
	// Sanity check.
	ASSERT(new_size > heap->end_address - heap->start_address);

	// Get the nearest following page boundary.
	if((new_size & 0xFFFFF000) != 0) {
		new_size &= 0xFFFFF000;
		new_size += 0x1000;
	}

	// Make sure we are not overreaching ourselves.
	ASSERT(heap->start_address+new_size <= heap->max_address);

	// This should always be on a page boundary.
	uint32_t old_size = heap->end_address-heap->start_address;

	// Expand until there is enough pages mapped
	uint32_t i = old_size;
	// new_size += 0x1000;

	while(i < new_size) {
		alloc_frame(paging_get_page(heap->start_address+i, true, kernel_directory), (heap->supervisor) ? true : false, true);
		i += 0x1000;
		pages_wired++;
	}

	// kprintf("Expanding heap from 0x%X until 0x%X\n", heap->end_address, heap->start_address + new_size);

	heap->end_address = heap->start_address+new_size;
}
示例#10
0
static Bool
load_initial_images (ModeInfo *mi)
{
  carousel_state *ss = &sss[MI_SCREEN(mi)];
  int i;
  Bool all_loaded_p = True;
  for (i = 0; i < ss->nframes; i++)
    if (! ss->frames[i]->loaded_p)
      all_loaded_p = False;

  if (all_loaded_p)
    {
      if (ss->nframes < MI_COUNT (mi))
        {
          /* The frames currently on the list are fully loaded.
             Start the next one loading.  (We run the image loader
             asynchronously, but we load them one at a time.)
           */
          load_image (mi, alloc_frame (mi));
        }
      else
        {
          /* The first batch of images are now all loaded!
             Stagger the expire times so that they don't all drop out at once.
           */
          time_t now = time((time_t *) 0);
          int i;

          for (i = 0; i < ss->nframes; i++)
            {
              image_frame *frame = ss->frames[i];
              frame->r = 1.0;
              frame->theta = i * 360.0 / ss->nframes;
              frame->expires = now + (duration * (i + 1));
              frame->mode = NORMAL;
            }

          /* Instead of always going clockwise, shuffle the expire times
             of the frames so that they drop out in a random order.
          */
          for (i = 0; i < ss->nframes; i++)
            {
              image_frame *frame1 = ss->frames[i];
              image_frame *frame2 = ss->frames[random() % ss->nframes];
              time_t swap = frame1->expires;
              frame1->expires = frame2->expires;
              frame2->expires = swap;
            }

          ss->awaiting_first_images_p = False;
        }
    }
      
  loading_msg (mi, ss->nframes-1);

  return !ss->awaiting_first_images_p;
}
示例#11
0
文件: thread.c 项目: almk277/ROSE
int thread_call_intern(Thread *t, Module *module, RA_Proc p_idx)
{
	const Segments *seg = &module->seg;
	const RMDProcedure *p = ptbl_get(seg, p_idx);
	if(alloc_frame(t, p) || save_procedure(t, p))
		return -1;
	t->pc.byte = text_get(seg, p->addr);
	t->procs->module = module;
	return 0;
}
示例#12
0
  void MethodBuilder::setup() {
    std::vector<Type*> ftypes;
    ftypes.push_back(ls_->ptr_type("VM"));
    ftypes.push_back(ls_->ptr_type("CallFrame"));
    ftypes.push_back(ls_->ptr_type("Executable"));
    ftypes.push_back(ls_->ptr_type("Module"));
    ftypes.push_back(ls_->ptr_type("Arguments"));

    FunctionType* ft = FunctionType::get(ls_->ptr_type("Object"), ftypes, false);

    std::ostringstream ss;
    ss << std::string("_X_")
       << ls_->enclosure_name(info_.method())
       << "#"
       << ls_->symbol_debug_str(info_.method()->name())
       << "@" << ls_->add_jitted_method();

    llvm::Function* func = Function::Create(ft, GlobalValue::ExternalLinkage,
                            ss.str().c_str(), ls_->module());

    Function::arg_iterator ai = func->arg_begin();
    llvm::Value* vm =   ai++; vm->setName("state");
    llvm::Value* prev = ai++; prev->setName("previous");
    exec = ai++; exec->setName("exec");
    module = ai++; module->setName("mod");
    llvm::Value* args = ai++; args->setName("args");

    BasicBlock* block = BasicBlock::Create(ls_->ctx(), "entry", func);
    builder_.SetInsertPoint(block);

    info_.context().set_function(func);

    info_.set_vm(vm);
    info_.set_args(args);
    info_.set_previous(prev);
    info_.set_entry(block);

    alloc_frame("method_body");

    check_arity();

    // check_self_type();

    initialize_frame(vmm_->stack_size);

    nil_stack(vmm_->stack_size, constant(cNil, obj_type));

    import_args();

    import_args_ = b().GetInsertBlock();

    b().CreateBr(body_);
    b().SetInsertPoint(body_);
  }
示例#13
0
文件: elf.c 项目: codyd51/axle
bool elf_load_segment(page_directory_t* new_dir, unsigned char* src, elf_phdr* seg) {
	//loadable?
	if (seg->type != PT_LOAD) {
		printf_err("Tried to load non-loadable segment");
		printk_err("Tried to load non-loadable segment");
		return false; 
	}

	unsigned char* src_base = src + seg->offset;
	//figure out range to map this binary to in virtual memory
	uint32_t dest_base = seg->vaddr;
	uint32_t dest_limit = dest_base + seg->memsz;

	printf("dest_base %x dest_limit %x\n", dest_base, dest_limit);
	//alloc enough mem for new task
	for (uint32_t i = dest_base, page_counter = 0; i <= dest_limit; i += PAGE_SIZE, page_counter++) {
		page_t* page = get_page(i, 1, new_dir);
		ASSERT(page, "elf_load_segment couldn't get page in new addrspace at %x\n", i);
		bool got_frame = alloc_frame(page, 0, 0);
		ASSERT(got_frame, "elf_load_segment couldn't alloc frame for page %x\n", i);
		
		char* pagebuf = kmalloc_a(PAGE_SIZE);
		page_t* local_page = get_page((uint32_t)pagebuf, 0, page_dir_current());
		ASSERT(local_page, "couldn't get local_page!");
		int old_frame = local_page->frame;
		local_page->frame = page->frame;
		invlpg(pagebuf);

		//create buffer in current address space,
		//copy data,
		//and then map frame into new address space
		memset(pagebuf, 0, (dest_limit - dest_base));
		//only seg->filesz bytes are garuanteed to be in the file!
		//_not_ memsz
		//any extra bytes between filesz and memsz should be set to 0, which is done above
		//memcpy(dest_base, src_base, seg->filesz);
		memcpy(pagebuf, src_base + (page_counter * PAGE_SIZE), seg->filesz);

		//now that we've copied the data in the local address space, 
		//get the page in local address space, 
		//and copy backing physical frame data to physical frame of
		//page in new address space

		//now that the buffer has been copied, we can safely free the buffer
		local_page->frame = old_frame;
		invlpg(pagebuf);
		kfree(pagebuf);
	}

	// Copy data
	//memset((void*)dest_base, 0, (void*)(dest_limit - dest_base));

	return true;
}
示例#14
0
static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
{
    QSVFrame *frame, **last;
    int ret;

    qsv_clear_unused_frames(q);

    frame = q->work_frames;
    last  = &q->work_frames;
    while (frame) {
        if (!frame->used) {
            ret = alloc_frame(avctx, q, frame);
            if (ret < 0)
                return ret;
            *surf = &frame->surface;
            return 0;
        }

        last  = &frame->next;
        frame = frame->next;
    }

    frame = av_mallocz(sizeof(*frame));
    if (!frame)
        return AVERROR(ENOMEM);
    frame->frame = av_frame_alloc();
    if (!frame->frame) {
        av_freep(&frame);
        return AVERROR(ENOMEM);
    }
    *last = frame;

    ret = alloc_frame(avctx, q, frame);
    if (ret < 0)
        return ret;

    *surf = &frame->surface;

    return 0;
}
示例#15
0
文件: heap.c 项目: bhamrick/gansu
int expand(size_t newsize, heap_t* heap) {
	if(newsize < heap->end_addr - heap->start_addr) return 0;
	if(newsize & 0xFFF) {
		newsize &= 0xFFFFF000;
		newsize += 0x1000;
	}
	if(newsize > heap->max_addr - heap->start_addr) return 0;
	u32int i = heap->end_addr - heap->start_addr;
	while(i < newsize) {
		alloc_frame( get_page(heap->start_addr+i, 1, kernel_directory), 
			(heap->super)?1:0, (heap->ronly)?0:1);
		i += 0x1000;
	}
	heap->end_addr = heap->start_addr+newsize;
	return 1;
}
示例#16
0
int main(int argc, char **argv)
{
    SDL_Event *event = av_mallocz(sizeof(SDL_Event));
    Content *content = av_mallocz(sizeof(Content));
    Media *video = av_mallocz(sizeof(Media));
    Media *audio = av_mallocz(sizeof(Media));
    State *state = av_mallocz(sizeof(State));
    SDL_Thread *video_decode_tid1;
    SDL_Thread *video_decode_tid2;
    SDL_Thread *read_pkt_tid;
    SDL_Thread *refresh_tid;
//    InitPool(2);
    state->content = content;
    state->video = video;
    state->audio = audio;
    init_video(video);
    if(argc < 2) {
	LOGE("Usage : play <content>");
	exit(1);
    }
    av_register_all();
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
	LOGE("fail to initialize SDL");
	exit(1);
    }
    av_strlcpy(content->name, argv[1], sizeof(content->name));
    LOGE("addr : %x", video->frame_buf);
    get_content_info(content);
    LOGI("finding streams");
    find_av_streams(content, video, audio);
    LOGI("finding decoder");
    find_decoder(video);
    video->get_info(video);
    LOGI("creating reading thread...");
    read_pkt_tid = SDL_CreateThread(queue_av_pkt, "read", state);
    LOGI("initing screen");
    init_screen(video);
//    LOGI("alloc frame");
    alloc_frame(video);
    LOGI("alloc all the frame");
//    alloc_all_frame(video);
    LOGI("creating decode thread1...");
    video_decode_tid1 = SDL_CreateThread(decode_video, "decode1", video);    
    refresh(state, 50);
    event_handle(event);
    return 0;
}
示例#17
0
std::shared_ptr<AVFrame> make_av_audio_frame(const core::const_frame& frame, const core::video_format_desc& format_desc)
{
    auto av_frame = alloc_frame();

    const auto& buffer = frame.audio_data();

    // TODO (fix) Use sample_format_desc.
    av_frame->channels       = format_desc.audio_channels;
    av_frame->channel_layout = av_get_default_channel_layout(av_frame->channels);
    av_frame->sample_rate    = format_desc.audio_sample_rate;
    av_frame->format         = AV_SAMPLE_FMT_S32;
    av_frame->nb_samples     = static_cast<int>(buffer.size() / av_frame->channels);
    FF(av_frame_get_buffer(av_frame.get(), 32));
    std::memcpy(av_frame->data[0], buffer.data(), buffer.size() * sizeof(buffer.data()[0]));

    return av_frame;
}
示例#18
0
文件: heap.c 项目: orodley/studix
void expand(Heap *heap, size_t new_size)
{
	// Sanity check
	ASSERT(heap->start_addr + new_size > heap->end_addr);

	new_size = align_up(new_size);

	// We don't want to expand over the max address
	ASSERT(heap->start_addr + new_size <= heap->max_addr);

	size_t old_size = heap->end_addr - heap->start_addr;

	for (size_t i = old_size; i < new_size; i += PAGE_SIZE)
		alloc_frame(get_page(heap->start_addr + i, 1, kernel_dir),
				heap->supervisor, heap->readonly);

	heap->end_addr = heap->start_addr + new_size;
}
示例#19
0
gboolean tilem_animation_append_frame(TilemAnimation *anim,
                                      const TilemLCDBuffer *buf,
                                      int duration)
{
	TilemAnimFrame *frm;

	g_return_val_if_fail(TILEM_IS_ANIMATION(anim), FALSE);
	g_return_val_if_fail(anim->end != NULL, FALSE);
	g_return_val_if_fail(buf != NULL, FALSE);
	g_return_val_if_fail(buf->data != NULL, FALSE);
	g_return_val_if_fail(buf->height == anim->display_height, FALSE);
	g_return_val_if_fail(buf->rowstride == anim->frame_rowstride, FALSE);

	if (anim->out_of_memory)
		return FALSE;

	if (anim->end->contrast == buf->contrast
	    && (anim->last_stamp == buf->stamp
	        || !memcmp(anim->end->data, buf->data, anim->frame_size))) {
		anim->end->duration += duration;
	}
	else {
		if (anim->end->duration == 0) {
			frm = anim->end;
		}
		else {
			frm = alloc_frame(anim->frame_size);
			if (!frm) {
				anim->out_of_memory = TRUE;
				return FALSE;
			}
			anim->end->next = frm;
			anim->end = frm;
		}

		frm->contrast = buf->contrast;
		frm->duration = duration;
		memcpy(frm->data, buf->data, anim->frame_size);
	}

	anim->last_stamp = buf->stamp;
	return TRUE;
}
示例#20
0
文件: syscall.c 项目: klange/ponyos
static int sys_sbrk(int size) {
	process_t * proc = (process_t *)current_process;
	if (proc->group != 0) {
		proc = process_from_pid(proc->group);
	}
	spin_lock(proc->image.lock);
	uintptr_t ret = proc->image.heap;
	uintptr_t i_ret = ret;
	ret = (ret + 0xfff) & ~0xfff; /* Rounds ret to 0x1000 in O(1) */
	proc->image.heap += (ret - i_ret) + size;
	while (proc->image.heap > proc->image.heap_actual) {
		proc->image.heap_actual += 0x1000;
		assert(proc->image.heap_actual % 0x1000 == 0);
		alloc_frame(get_page(proc->image.heap_actual, 1, current_directory), 0, 1);
		invalidate_tables_at(proc->image.heap_actual);
	}
	spin_unlock(proc->image.lock);
	return ret;
}
示例#21
0
文件: pmm.c 项目: Nov11/jamesos
u32int pmm_alloc_page()
{
	/*if(pmm_paging_active == 0){
		u32int ret = pmm_location;
		pmm_location += 0x1000;
		return ret;
	}
	
	if(pmm_stack_loc == PMM_STACK_ADDR){
		PANIC("pmm_alloc_page");
	}
	
	pmm_stack_loc -= sizeof(u32int);
	u32int* stack = (u32int*)pmm_stack_loc;
	return *stack;
	*/
	u32int ret = alloc_frame();
	return ret;
}
示例#22
0
文件: kheap.c 项目: oridb/PhotonOS
void expand(uint32_t new_size, heap_t *heap)
{
	ASSERT(new_size > heap->end_address - heap->start_address);
	
	if ((new_size & 0xFFFFF000) != 0) {
		new_size &= 0xFFFFF000;
		new_size += 0x1000;
	}
	
	ASSERT(heap->start_address + new_size <= heap->max_address);
	
	uint32_t old_size = heap->end_address-heap->start_address;
	uint32_t i = old_size;
	while (i < new_size) {
		alloc_frame( get_page(heap->start_address+i, 1, kernel_directory),
				(heap->supervisor)?1:0, (heap->readonly)?0:1);
		i += 0x1000;
	}
	heap->end_address = heap->start_address+new_size;
}
示例#23
0
文件: vm.c 项目: Fluray/OrzOs
void vma_nopage(vma_t *vma, u32int vaddr)
{
    if (!vma)
        return;

    /*printk("cr2 %p\n", current_task->dir->addr);*/
    /*MAGIC_BREAK();*/
    alloc_frame(get_page(vaddr, 1, current_task->dir), 1, vma->flags & VMA_WRITE);
    switch_page_directory(current_task->dir);

    if (vma->flags & VMA_ANON) {
        if (vma->flags & VMA_STACK) {
            vma->vm->end_stack -= 0x1000;
            vma->start -= 0x1000;
        }
        return;
    }

    if (vma->flags & VMA_FILE) {
        file_mapping_t *f_map = (file_mapping_t*)vma->priv;
        u32int size = 0x1000;

        u32int off = vaddr - vma->start;
        if (off >= f_map->size) {
            memset((void*)vaddr, 0, size);
        } else {
            file_lseek(f_map->file, f_map->offset + off, SEEK_SET);
            if (off + size > f_map->size) {
                /*printk("file_read: %p, size: %d\n", vaddr, f_map->size - off);*/
                /*printk("memset: %p, size: %d\n", vma->start+f_map->size, size + off - f_map->size);*/
                file_read(f_map->file, (u8int*)vaddr, f_map->size - off);
                memset((void*)(vma->start + f_map->size), 0, size + off - f_map->size);
            } else {
                /*printk("file_read: %p, size: %d\n", vaddr, size);*/
                file_read(f_map->file, (u8int*)vaddr, size);
            }
        }
    }

}
示例#24
0
static void check_persistent() {
  frame_t *frame = alloc_frame();
  struct stat st = {0};
  char datadir[512] = {0};

  CU_ASSERT_FATAL(frame != NULL);

  // set test data to a frame
  strncpy(frame->name, "SEND", 4);
  stomp_setdata("content-length:4", 16, &frame->h_attrs, NULL);
  stomp_setdata("hoge:fuga",        9, &frame->h_attrs, NULL);
  stomp_setdata("abcd",             4, &frame->h_data, NULL);
  frame->size = 38; // 5(SEND\n) + (17 + 10)(headers) + 1(separation) + 5(body)

  CU_ASSERT(persist_frame(frame, QNAME) == RET_SUCCESS);

  // delay to flush data persistently
  sleep(1);

  sprintf(datadir, "%s/%s/data", config.datadir, QNAME);

  CU_ASSERT(stat(datadir, &st) == 0);
  CU_ASSERT(st.st_size == frame->size);
}
示例#25
0
int reciever::assemble_and_out()
{
	if (current_frame_id < 0 || current_packet_count == 0)
		return 0;

	int payload_packet_count = 0;
	int parity_packet_count;
	for(int i=0; i<256; i++)
	{
		if (packets[i].payload_packet_count)
		{
			payload_packet_count = packets[i].payload_packet_count;
			parity_packet_count = packets[i].parity_packet_count;
			break;
		}
	}

	// we have enough valid packets? packets properly formed?
	if (current_packet_count < payload_packet_count || payload_packet_count <= 0 || parity_packet_count <= 0)
	{
		// no, clear up and exit
		current_frame_id = -1;
		current_packet_count = 0;
		for(int i=0; i<256; i++)
		{
			memset(&packets[i], 0, sizeof(raw_packet));
			packets[i].payload_packet_count = 0;
		}
	}
	
	// assemble and do FEC if needed

	// create erasures
	int slice_size = payload_packet_count + parity_packet_count;
	int erasures[256];
	int erasures_count = 0;
	for(int i=0; i<slice_size; i++)
		if (packets[i].payload_packet_count == 0)	// current only missing packets checked, TODO: CRC
			erasures[erasures_count++] = i;

	// decode and output
	rsDecoder decoder;
	bool error = false;
	decoder.init(parity_packet_count);
	uint8_t slice_data[256];
	int max_packet_payload_size = sizeof(raw_packet)-5;
	frame * f = alloc_frame(payload_packet_count * max_packet_payload_size, current_frame_id, true);
	for(int i=0; i<max_packet_payload_size; i++)
	{
		for(int j=0; j<slice_size; j++)
			slice_data[j] = packets[j].data[i];		

		if (!decoder.correct_errors_erasures(slice_data, slice_size, erasures_count, erasures))
			error = true;


		for(int j=0; j<payload_packet_count; j++)
		{
			((uint8_t*)f->payload)[j*max_packet_payload_size + i] = slice_data[j];			
		}
	}

	f->integrality = !error;
	if (cb)
		cb->handle_frame(*f);
	release_frame(f);

	// clear up
	current_frame_id = -1;
	current_packet_count = 0;
	for(int i=0; i<256; i++)
	{
		packets[i].payload_packet_count = 0;
		memset(&packets[i], 0, sizeof(raw_packet));
	}
		
	return 0;
}
示例#26
0
文件: sys.c 项目: chuckleplant/ZeOS
int sys_fork()
{
  update_user_to_system();
  int PID=-1;
  int i;
  int j;
  // creates the child process
/*
 a) Get a free task_struct for the process. If there is no space for a new process, an error
   will be returned.
b) Inherit system data: copy the parent’s task_union to the child. Determine whether it is necessary to modify the page table of the parent to access the child’s system data. The
   copy_data function can be used to copy.
c) Initialize field dir_pages_baseAddr with a new directory to store the process address
   space using the allocate_DIR routine.
d) Search physical pages in which to map logical pages for data+stack of the child process
   (using the alloc_frames function). If there is no enough free pages, an error will be
   return.
*/

//a
  if(list_empty( &freequeue )){
    update_system_to_user(current());
    return -ENOMEM;
  }
  struct list_head * freequeue_head = list_first( &freequeue );
  struct task_struct * child_struct  = list_head_to_task_struct(freequeue_head);
  list_del(freequeue_head); // not in freequeue anymore
  
//b 
  struct task_struct * current_struct = current();
  union task_union * current_union = (union task_union *) current_struct;
  union task_union * child_union = (union task_union *) child_struct;
  copy_data(current_union, child_union, sizeof(union task_union));
  // TODO determine  whether it is necessary to modify the page table of the parent to access the child’s system data

//c 
  allocate_DIR(child_struct);

//d
  int physical_pages[NUM_PAG_DATA];
  for(i = 0; i < NUM_PAG_DATA; ++i)
  {
    physical_pages[i] = alloc_frame();
    if( physical_pages[i] < 0){
      for(j = i-1; j >= 0; j--)
      {
        free_frame((unsigned int)j);
      }
      update_system_to_user(current());
      return -EAGAIN;
    }
  }


/*
e) Inherit user data:
    i) Create new address space: Access page table of the child process through the direc-
       tory field in the task_struct to initialize it (get_PT routine can be used):
       A) Page table entries for the system code and data and for the user code can be a
          copy of the page table entries of the parent process (they will be shared)
*/
  page_table_entry * child_pt = get_PT(child_struct);
  page_table_entry * parent_pt = get_PT(current_struct);
  int child_logical_address;
  for(child_logical_address = 0; child_logical_address < NUM_PAG_KERNEL + NUM_PAG_CODE; child_logical_address++)
  {
    int physical_parent_frame = get_frame(parent_pt, child_logical_address);
    set_ss_pag( child_pt, child_logical_address, physical_parent_frame);
  }
/*     B) Page table entries for the user data+stack have to point to new allocated pages
          which hold this region*/

  for(; child_logical_address < NUM_PAG_KERNEL + NUM_PAG_CODE + NUM_PAG_DATA; child_logical_address++)
  {
    set_ss_pag(child_pt, child_logical_address, physical_pages[child_logical_address - (NUM_PAG_KERNEL + NUM_PAG_CODE)]);
  }



/*
   ii) Copy the user data+stack pages from the parent process to the child process. The
       child’s physical pages cannot be directly accessed because they are not mapped in
       the parent’s page table. In addition, they cannot be mapped directly because the
       logical parent process pages are the same. They must therefore be mapped in new
       entries of the page table temporally (only for the copy). Thus, both pages can be
       accessed simultaneously as follows:
       A) Use temporal free entries on the page table of the parent. Use the set_ss_pag and
          del_ss_pag functions.
       B) Copy data+stack pages.
       C) Free temporal entries in the page table and flush the TLB to really disable the
          parent process to access the child pages.
*/

  // direccion logica del systemcode+systemdata+usercode = direccion logica datos user
  



  
  int parent_log = NUM_PAG_KERNEL + NUM_PAG_CODE;  
  for(i = 0; i < NUM_PAG_DATA; ++i){
  	set_ss_pag(parent_pt, parent_log + NUM_PAG_DATA + i, physical_pages[i]);
  	copy_data( (void*) ((parent_log + i) * PAGE_SIZE), (void*) ((parent_log + NUM_PAG_DATA + i) * PAGE_SIZE), PAGE_SIZE );
	del_ss_pag(parent_pt, parent_log + NUM_PAG_DATA + i);
  }
  
  
  
  //set_cr3(parent_pt); // flush tlb fallaba, por que? TODO
  set_cr3(get_DIR(current_struct));

/*
f) Assign a new PID to the process. The PID must be different from its position in the
    task_array table.
g) Initialize the fields of the task_struct that are not common to the child.
     i) Think about the register or registers that will not be common in the returning of the
        child process and modify its content in the system stack so that each one receive its
        values when the context is restored.
h) Prepare the child stack emulating a call to context_switch and be able to restore its
    context in a known position. The stack of the new process must be forged so it can be
    restored at some point in the future by a task_switch. In fact the new process has to
    restore its hardware context and continue the execution of the user process, so you can
    create a routine ret_from_fork which does exactly this. And use it as the restore point
    like in the idle process initialization 4.4.
 i) Insert the new process into the ready list: readyqueue. This list will contain all processes
    that are ready to execute but there is no processor to run them.
 j) Return the pid of the child process.
*/
  if(_PID == INT_MAX){
    update_system_to_user(current());
    return -1; // please restart
  }
  child_struct->PID = _PID++;
  PID = child_struct->PID;

/* 
* 0		-19
* ret_from_fork	-18
* sys_call_handler // -17
* SAVEALL // -16	
* iret    // -5
*/	
 
  
  child_struct->kernel_esp = (unsigned long *)&child_union->stack[KERNEL_STACK_SIZE-19];
  child_union->stack[KERNEL_STACK_SIZE-19] = 0;
  child_union->stack[KERNEL_STACK_SIZE-18] = (int)ret_from_fork;

  list_add_tail(&child_struct->list, &readyqueue);
  child_struct->stats.elapsed_total_ticks = get_ticks();
  child_struct->stats.user_ticks = 0;
  child_struct->stats.system_ticks = 0;
  child_struct->stats.blocked_ticks = 0;
  child_struct->stats.ready_ticks = 0;
  child_struct->stats.total_trans = 0; 
  child_struct->stats.remaining_ticks = 0;
//  last_forked_child = child_struct = 0;
  update_system_to_user(current());
  return PID; 
}
示例#27
0
libav_encoder* libav_encoder::create( const char *path, unsigned width, unsigned height,
                                      const std::pair<int, int>& fps, int bit_rate )
{
    impl *m = new impl;
    for (;;) {
        m->format = av_guess_format(NULL, path, NULL);
        if (!m->format)
            break;

        if ((m->format->flags & AVFMT_NOFILE) || (m->format->video_codec == CODEC_ID_NONE))
            break;

        m->formatCtx = avformat_alloc_context();
        if (!m->formatCtx)
            break;
        m->formatCtx->oformat = m->format;

        {
            #if LIBAVFORMAT_VERSION_MAJOR >= 54
                m->stream = avformat_new_stream(m->formatCtx, 0);
            #else
                m->stream = av_new_stream(m->formatCtx, 0);
            #endif
            if (!m->stream) {
                fprintf(stderr, "Could not alloc stream\n");
                break;
            }
            m->codecCtx = m->stream->codec;

            m->codecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
            if (strcmp(m->format->name, "avi") == 0) {
                m->codecCtx->codec_id = CODEC_ID_RAWVIDEO;
            } else {
                m->codecCtx->codec_id = m->format->video_codec;
            }

            AVCodec *codec = avcodec_find_encoder(m->codecCtx->codec_id);
            if (!codec)
                break;

            if (strcmp(m->format->name, "avi") == 0) {
                m->codecCtx->pix_fmt = PIX_FMT_BGR24;
            } else {
                if (codec->pix_fmts)
                    m->codecCtx->pix_fmt = codec->pix_fmts[0];
                else
                    m->codecCtx->pix_fmt = PIX_FMT_YUV420P;
            }

            m->codecCtx->bit_rate = 8000000;
            m->codecCtx->width = width;   /* resolution must be a multiple of two */
            m->codecCtx->height = height;
            m->codecCtx->time_base.num = fps.second;
            m->codecCtx->time_base.den = fps.first;
            m->codecCtx->gop_size = 12; /* emit one intra frame every twelve frames at most */

            if(m->formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
                m->codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;

                #if LIBAVFORMAT_VERSION_MAJOR >= 54
                    if (avcodec_open2(m->codecCtx, codec, NULL) < 0) break;
                #else
                    if (avcodec_open(m->codecCtx, codec) < 0) break;
                #endif

            if (!(m->formatCtx->oformat->flags & AVFMT_RAWPICTURE)) {
                m->output_size = m->codecCtx->width * m->codecCtx->height * 4;
                m->output_buffer = (uint8_t*)av_malloc(m->output_size);
            }

            if (!alloc_frame(&m->frame1, &m->buffer1, m->codecCtx->pix_fmt, m->codecCtx->width, m->codecCtx->height))
                break;
            if (!alloc_frame(&m->frame0, &m->buffer0, PIX_FMT_RGB32, m->codecCtx->width, m->codecCtx->height))
                break;
        }

        #if LIBAVFORMAT_VERSION_MAJOR >= 54
            if (avio_open(&m->formatCtx->pb, path, AVIO_FLAG_WRITE) < 0) break;
            avformat_write_header(m->formatCtx, NULL);
        #else
            if (url_fopen(&m->formatCtx->pb, path, URL_WRONLY) < 0) break;
            av_write_header(m->formatCtx);
        #endif

        m->swsCtx = sws_getContext( m->codecCtx->width, m->codecCtx->height, PIX_FMT_RGB32,
                                    m->codecCtx->width, m->codecCtx->height, m->codecCtx->pix_fmt,
                                    SWS_POINT, NULL, NULL, NULL );
        if (!m->swsCtx)
            break;

        return new libav_encoder(m);
    }
    delete m;
    return 0;
}
示例#28
0
int exec_elf(char * path, fs_node_t * file, int argc, char ** argv, char ** env, int interp) {
	Elf32_Header header;

	read_fs(file, 0, sizeof(Elf32_Header), (uint8_t *)&header);

	if (header.e_ident[0] != ELFMAG0 ||
	    header.e_ident[1] != ELFMAG1 ||
	    header.e_ident[2] != ELFMAG2 ||
	    header.e_ident[3] != ELFMAG3) {
		debug_print(ERROR, "Not a valid ELF executable.");
		close_fs(file);
		return -1;
	}

	if (!interp) {
		current_process->name = strdup(path);
		current_process->cmdline = argv;
	}

	if (file->mask & 0x800) {
		debug_print(WARNING, "setuid binary executed [%s, uid:%d]", file->name, file->uid);
		current_process->user = file->uid;
	}

	for (uintptr_t x = 0; x < (uint32_t)header.e_phentsize * header.e_phnum; x += header.e_phentsize) {
		Elf32_Phdr phdr;
		read_fs(file, header.e_phoff + x, sizeof(Elf32_Phdr), (uint8_t *)&phdr);
		if (phdr.p_type == PT_DYNAMIC) {
			/* Dynamic */
			close_fs(file);

			/* Find interpreter? */
			debug_print(WARNING, "Dynamic executable");

			unsigned int nargc = argc + 3;
			char * args[nargc];
			args[0] = "ld.so";
			args[1] = "-e";
			args[2] = strdup(current_process->name);
			int j = 3;
			for (int i = 0; i < argc; ++i, ++j) {
				args[j] = argv[i];
			}
			args[j] = NULL;

			fs_node_t * file = kopen("/lib/ld.so",0);
			if (!file) return -1;

			return exec_elf(NULL, file, nargc, args, env, 1);
		}
	}

	uintptr_t entry = (uintptr_t)header.e_entry;
	uintptr_t base_addr = 0xFFFFFFFF;
	uintptr_t end_addr  = 0x0;

	for (uintptr_t x = 0; x < (uint32_t)header.e_phentsize * header.e_phnum; x += header.e_phentsize) {
		Elf32_Phdr phdr;
		read_fs(file, header.e_phoff + x, sizeof(Elf32_Phdr), (uint8_t *)&phdr);
		if (phdr.p_type == PT_LOAD) {
			if (phdr.p_vaddr < base_addr) {
				base_addr = phdr.p_vaddr;
			}
			if (phdr.p_memsz + phdr.p_vaddr > end_addr) {
				end_addr = phdr.p_memsz + phdr.p_vaddr;
			}
		}
	}

	current_process->image.entry = base_addr;
	current_process->image.size  = end_addr - base_addr;

	release_directory_for_exec(current_directory);
	invalidate_page_tables();


	for (uintptr_t x = 0; x < (uint32_t)header.e_phentsize * header.e_phnum; x += header.e_phentsize) {
		Elf32_Phdr phdr;
		read_fs(file, header.e_phoff + x, sizeof(Elf32_Phdr), (uint8_t *)&phdr);
		if (phdr.p_type == PT_LOAD) {
			for (uintptr_t i = phdr.p_vaddr; i < phdr.p_vaddr + phdr.p_memsz; i += 0x1000) {
				/* This doesn't care if we already allocated this page */
				alloc_frame(get_page(i, 1, current_directory), 0, 1);
				invalidate_tables_at(i);
			}
			IRQ_RES;
			read_fs(file, phdr.p_offset, phdr.p_filesz, (uint8_t *)phdr.p_vaddr);
			IRQ_OFF;
			size_t r = phdr.p_filesz;
			while (r < phdr.p_memsz) {
				*(char *)(phdr.p_vaddr + r) = 0;
				r++;
			}
		}
	}

	close_fs(file);

	for (uintptr_t stack_pointer = USER_STACK_BOTTOM; stack_pointer < USER_STACK_TOP; stack_pointer += 0x1000) {
		alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1);
		invalidate_tables_at(stack_pointer);
	}

	/* Collect arguments */
	int envc = 0;
	for (envc = 0; env[envc] != NULL; ++envc);

	/* Format auxv */
	Elf32_auxv auxv[] = {
		{256, 0xDEADBEEF},
		{0, 0}
	};
	int auxvc = 0;
	for (auxvc = 0; auxv[auxvc].id != 0; ++auxvc);
	auxvc++;

	uintptr_t heap = current_process->image.entry + current_process->image.size;
	while (heap & 0xFFF) heap++;
	alloc_frame(get_page(heap, 1, current_directory), 0, 1);
	invalidate_tables_at(heap);
	char ** argv_ = (char **)heap;
	heap += sizeof(char *) * (argc + 1);
	char ** env_ = (char **)heap;
	heap += sizeof(char *) * (envc + 1);
	void * auxv_ptr = (void *)heap;
	heap += sizeof(Elf32_auxv) * (auxvc);

	for (int i = 0; i < argc; ++i) {
		size_t size = strlen(argv[i]) * sizeof(char) + 1;
		for (uintptr_t x = heap; x < heap + size + 0x1000; x += 0x1000) {
			alloc_frame(get_page(x, 1, current_directory), 0, 1);
		}
		invalidate_tables_at(heap);
		argv_[i] = (char *)heap;
		memcpy((void *)heap, argv[i], size);
		heap += size;
	}
	/* Don't forget the NULL at the end of that... */
	argv_[argc] = 0;

	for (int i = 0; i < envc; ++i) {
		size_t size = strlen(env[i]) * sizeof(char) + 1;
		for (uintptr_t x = heap; x < heap + size + 0x1000; x += 0x1000) {
			alloc_frame(get_page(x, 1, current_directory), 0, 1);
		}
		invalidate_tables_at(heap);
		env_[i] = (char *)heap;
		memcpy((void *)heap, env[i], size);
		heap += size;
	}
	env_[envc] = 0;

	memcpy(auxv_ptr, auxv, sizeof(Elf32_auxv) * (auxvc));

	current_process->image.heap        = heap; /* heap end */
	current_process->image.heap_actual = heap + (0x1000 - heap % 0x1000);
	alloc_frame(get_page(current_process->image.heap_actual, 1, current_directory), 0, 1);
	invalidate_tables_at(current_process->image.heap_actual);
	current_process->image.user_stack  = USER_STACK_TOP;

	current_process->image.start = entry;

	/* Go go go */
	enter_user_jmp(entry, argc, argv_, USER_STACK_TOP);

	/* We should never reach this code */
	return -1;
}
示例#29
0
/**
 * Load and execute a static ELF binary.
 *
 * We make one assumption on the location the binary expects to be loaded
 * at: that it be outside of the kernel memory space.
 *
 * Arguments are passed to the stack of the user application so that they
 * can be read properly.
 *
 * TODO: Environment variables should be loaded somewhere.
 *
 * HACK: ELF verification isn't complete.
 *
 * @param path Path to the executable to attempt to execute.
 * @param argc Number of arguments (because I'm not counting for you)
 * @param argv Pointer to a string of arguments
 */
int
exec(
    char *  path, /* Path to the executable to run */
    int     argc, /* Argument count (ie, /bin/echo hello world = 3) */
    char ** argv, /* Argument strings (including executable path) */
    char ** env   /* Environmen variables */
) {

    /* Open the file */
    fs_node_t * file = kopen(path,0);
    if (!file) {
        /* Command not found */
        return 0;
    }
    /* Read in the binary contents */
    for (uintptr_t x = 0x30000000; x < 0x30000000 + file->length; x += 0x1000) {
        alloc_frame(get_page(x, 1, current_directory), 0, 1);
    }
    Elf32_Header * header = (Elf32_Header *)0x30000000; //(Elf32_Header *)malloc(file->length + 100);
    read_fs(file, 0, file->length, (uint8_t *)header);

    current_process->name = malloc(strlen(path) + 1);
    memcpy(current_process->name, path, strlen(path) + 1);

    /* Alright, we've read the binary, time to load the loadable sections */
    /* Verify the magic */
    if (	header->e_ident[0] != ELFMAG0 ||
            header->e_ident[1] != ELFMAG1 ||
            header->e_ident[2] != ELFMAG2 ||
            header->e_ident[3] != ELFMAG3) {
        /* What? This isn't an ELF... */
        kprintf("Fatal: Not a valid ELF executable.\n");
        for (uintptr_t x = 0x30000000; x < 0x30000000 + file->length; x += 0x1000) {
            free_frame(get_page(x, 0, current_directory));
        }
        close_fs(file);
        return -1;
    }

    /* Load the loadable segments from the binary */
    for (uintptr_t x = 0; x < (uint32_t)header->e_shentsize * header->e_shnum; x += header->e_shentsize) {
        /* read a section header */
        Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)header + (header->e_shoff + x));
        if (shdr->sh_addr) {
            /* If this is a loadable section, load it up. */
            if (shdr->sh_addr < current_process->image.entry) {
                /* If this is the lowest entry point, store it for memory reasons */
                current_process->image.entry = shdr->sh_addr;
            }
            if (shdr->sh_addr + shdr->sh_size - current_process->image.entry > current_process->image.size) {
                /* We also store the total size of the memory region used by the application */
                current_process->image.size = shdr->sh_addr + shdr->sh_size - current_process->image.entry;
            }
            for (uintptr_t i = 0; i < shdr->sh_size + 0x2000; i += 0x1000) {
                /* This doesn't care if we already allocated this page */
                alloc_frame(get_page(shdr->sh_addr + i, 1, current_directory), 0, 1);
            }
            if (shdr->sh_type == SHT_NOBITS) {
                /* This is the .bss, zero it */
                memset((void *)(shdr->sh_addr), 0x0, shdr->sh_size);
            } else {
                /* Copy the section into memory */
                memcpy((void *)(shdr->sh_addr), (void *)((uintptr_t)header + shdr->sh_offset), shdr->sh_size);
            }
        }
    }

    /* Store the entry point to the code segment */
    uintptr_t entry = (uintptr_t)header->e_entry;

    /* Free the space we used for the ELF headers and files */
    for (uintptr_t x = 0x30000000; x < 0x30000000 + file->length; x += 0x1000) {
        free_frame(get_page(x, 0, current_directory));
    }
    close_fs(file);

    for (uintptr_t stack_pointer = USER_STACK_BOTTOM; stack_pointer < USER_STACK_TOP; stack_pointer += 0x1000) {
        alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1);
    }

    /* Collect arguments */
    int envc = 0;
    for (envc = 0; env[envc] != NULL; ++envc);

    /* Format auxv */
    Elf32_auxv auxv[] = {
        {256, 0xDEADBEEF},
        {0, 0}
    };
    int auxvc = 0;
    for (auxvc = 0; auxv[auxvc].id != 0; ++auxvc);

    uintptr_t heap = current_process->image.entry + current_process->image.size;
    alloc_frame(get_page(heap, 1, current_directory), 0, 1);
    char ** argv_ = (char **)heap;
    heap += sizeof(char *) * (argc + 1);
    char ** env_ = (char **)heap;
    heap += sizeof(char *) * (envc + 1);
    void * auxv_ptr = (void *)heap;
    heap += sizeof(Elf32_auxv) * (auxvc);

    for (int i = 0; i < argc; ++i) {
        alloc_frame(get_page(heap, 1, current_directory), 0, 1);
        argv_[i] = (char *)heap;
        memcpy((void *)heap, argv[i], strlen(argv[i]) * sizeof(char) + 1);
        heap += strlen(argv[i]) + 1;
    }
    /* Don't forget the NULL at the end of that... */
    argv_[argc] = 0;

    for (int i = 0; i < envc; ++i) {
        alloc_frame(get_page(heap, 1, current_directory), 0, 1);
        env_[i] = (char *)heap;
        memcpy((void *)heap, env[i], strlen(env[i]) * sizeof(char) + 1);
        heap += strlen(env[i]) + 1;
    }
    env_[envc] = 0;

    memcpy(auxv_ptr, auxv, sizeof(Elf32_auxv) * (auxvc));

    current_process->image.heap        = heap; /* heap end */
    current_process->image.heap_actual = heap + (0x1000 - heap % 0x1000);
    current_process->image.user_stack  = USER_STACK_TOP;
    while (current_process->fds->length < 3) {
        process_append_fd((process_t *)current_process, NULL);
    }

    current_process->image.start = entry;

    /* Go go go */
    enter_user_jmp(entry, argc, argv_, USER_STACK_TOP);

    /* We should never reach this code */
    return -1;
}
示例#30
0
std::shared_ptr<AVFrame> make_av_video_frame(const core::const_frame& frame, const core::video_format_desc& format_desc)
{
    auto av_frame = alloc_frame();

    auto pix_desc = frame.pixel_format_desc();

    auto planes = pix_desc.planes;
    auto format = pix_desc.format;

    const auto sar = boost::rational<int>(format_desc.square_width, format_desc.square_height) /
                     boost::rational<int>(format_desc.width, format_desc.height);

    av_frame->sample_aspect_ratio = {sar.numerator(), sar.denominator()};
    av_frame->width               = format_desc.width;
    av_frame->height              = format_desc.height;

    switch (format) {
        case core::pixel_format::rgb:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_RGB24;
            break;
        case core::pixel_format::bgr:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_BGR24;
            break;
        case core::pixel_format::rgba:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_RGBA;
            break;
        case core::pixel_format::argb:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_ARGB;
            break;
        case core::pixel_format::bgra:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_BGRA;
            break;
        case core::pixel_format::abgr:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_ABGR;
            break;
        case core::pixel_format::gray:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_GRAY8;
            break;
        case core::pixel_format::ycbcr: {
            int y_w = planes[0].width;
            int y_h = planes[0].height;
            int c_w = planes[1].width;
            int c_h = planes[1].height;

            if (c_h == y_h && c_w == y_w)
                av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV444P;
            else if (c_h == y_h && c_w * 2 == y_w)
                av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV422P;
            else if (c_h == y_h && c_w * 4 == y_w)
                av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV411P;
            else if (c_h * 2 == y_h && c_w * 2 == y_w)
                av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV420P;
            else if (c_h * 2 == y_h && c_w * 4 == y_w)
                av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV410P;

            break;
        }
        case core::pixel_format::ycbcra:
            av_frame->format = AVPixelFormat::AV_PIX_FMT_YUVA420P;
            break;
    }

    FF(av_frame_get_buffer(av_frame.get(), 32));

    // TODO (perf) Avoid extra memcpy.
    for (int n = 0; n < planes.size(); ++n) {
        for (int y = 0; y < av_frame->height; ++y) {
            std::memcpy(av_frame->data[n] + y * av_frame->linesize[n],
                        frame.image_data(n).data() + y * planes[n].linesize,
                        planes[n].linesize);
        }
    }

    return av_frame;
}