int main(void) { l4re_env_t *env = l4re_env(); // get environment l4_msg_regs_t *mr = l4_utcb_mr(); // get msg regs char *str = "Hello, world!\n"; const int str_length = 15; mr->mr[0] = L4_VCON_WRITE_OP; mr->mr[1] = str_length; memcpy(&mr->mr[2], str, str_length); l4_msgtag_t tag, ret; tag = l4_msgtag(L4_PROTO_LOG, // long label (protocol) 6, // unsigned words 0, // unsigned items 0); // unsigned flags ret = l4_ipc_send(env->log, // l4_cap_idx_t dest l4_utcb(), // l4_utcb_t *utcb tag, // l4_msgtag_t tag L4_IPC_SEND_TIMEOUT_0); // l4_timeout_t timeout if (l4_msgtag_has_error(ret)) fprintf(stderr, "Error in message tag.\n"); }
static void uxScreenUpdate(int x, int y, int w, int h) { (void)x; (void)y; (void)w; (void)h; if (!waiting) { lx_kill(ux_con_pid, LX_SIGUSR1); waiting = 1; while (l4_ipc_error(l4_ipc_send(updater_id, l4_utcb(), l4_msgtag(0, 0, 0, 0), L4_IPC_BOTH_TIMEOUT_0), l4_utcb())) { l4_sleep(1); } } }
void _l4threads_suspendall_c(void) { l4_msgdope_t result; if (sleepcount == leaflet.threadCount) { { l4_ipc_send(leaflet.gc, L4_IPC_SHORT_MSG, 0, //l4_umword_t snd_dword0, 0, //l4_umword_t snd_dword1, L4_IPC_NEVER, &result); } while (L4_IPC_ERROR(result) == L4_IPC_SECANCELED || L4_IPC_ERROR(result) == L4_IPC_SEABORTED); } while (1) l4thread_sleep_forever(); }
static void btn_repeat(void *data) { l4thread_started(NULL); for (;;) { l4_umword_t code, new_code, repeat, new_repeat; l4_msgdope_t result; int error; error = l4_ipc_receive(evh_l4id, L4_IPC_SHORT_MSG, &code, &repeat, L4_IPC_NEVER, &result); error = l4_ipc_send (evh_l4id, L4_IPC_SHORT_MSG, 0, 0, L4_IPC_NEVER, &result); if (!repeat) continue; for (;;) { /* wait for around 250ms */ error = l4_ipc_receive(evh_l4id, L4_IPC_SHORT_MSG, &new_code, &new_repeat, l4_ipc_timeout(0,0,976,8), &result); if (error == L4_IPC_RETIMEOUT && !key_pending) { /* no new key in the meantime -- start repeat. * wait for round 30ms */ for (;;) { if (__shift) { switch (code) { case KEY_UP: _key_scroll(SDOWN, 1); break; case KEY_PAGEUP: _key_scroll(SDOWN, 20); break; case KEY_DOWN: _key_scroll(SUP, 1); break; case KEY_PAGEDOWN: _key_scroll(SUP, 20); break; default: _add_key_if_not_too_busy(code); } } else { /* send key */ _add_key_if_not_too_busy(code); } /* wait for key up or other key down */ error = l4_ipc_receive(evh_l4id, L4_IPC_SHORT_MSG, &new_code, &repeat, l4_ipc_timeout(0,0,546,6), &result); if (error != L4_IPC_RETIMEOUT || key_pending) { /* new key or key_up received -- break repeat. * tricky: fall through until next send */ break; } } } if (error == 0) { code = new_code; repeat = new_repeat; /* new key or key_up received -- only reply, do not repeat */ error = l4_ipc_send(evh_l4id, L4_IPC_SHORT_MSG, 0, 0, L4_IPC_NEVER, &result); if (repeat) continue; break; } else if (key_pending) { code = key_code; repeat = key_repeat; key_pending = 0; if (repeat) continue; break; } else { /* ??? */ LOG("btn_repeat: ipc error %02x", error); break; } } } }
/* Our main function */ int main(void) { /* Get a capability slot for our new thread. */ l4_cap_idx_t t1 = l4re_util_cap_alloc(); l4_utcb_t *u = l4_utcb(); l4_exc_regs_t *e = l4_utcb_exc_u(u); l4_msgtag_t tag; int err; extern char _start[], _end[], _etext[]; if (l4_is_invalid_cap(t1)) return 1; /* Prevent pagefaults of our new thread because we do not want to * implement a pager as well. */ l4_touch_ro(_start, _end - _start + 1); l4_touch_rw(_etext, _end - _etext); /* Create the thread using our default factory */ tag = l4_factory_create_thread(l4re_env()->factory, t1); if (l4_msgtag_has_error(tag)) return 1; /* Setup the thread by setting the pager and task. */ l4_thread_control_start(); l4_thread_control_pager(l4re_env()->main_thread); l4_thread_control_exc_handler(l4re_env()->main_thread); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP); tag = l4_thread_control_commit(t1); if (l4_msgtag_has_error(tag)) return 2; /* Start the thread by finally setting instruction and stack pointer */ tag = l4_thread_ex_regs(t1, (l4_umword_t)thread, (l4_umword_t)thread_stack + sizeof(thread_stack), L4_THREAD_EX_REGS_TRIGGER_EXCEPTION); if (l4_msgtag_has_error(tag)) return 3; /* Receive initial exception from just started thread */ tag = l4_ipc_receive(t1, u, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) { printf("Umm, ipc error: %x\n", err); return 1; } /* We expect an exception IPC */ if (!l4_msgtag_is_exception(tag)) { printf("PF?: %lx %lx (not prepared to handle this) %ld\n", l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag)); return 1; } /* Fill out the complete register set of the new thread */ e->ip = (l4_umword_t)thread; e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack)); e->eax = 1; e->ebx = 4; e->ecx = 2; e->edx = 3; e->esi = 6; e->edi = 7; e->ebp = 5; /* Send a complete exception */ tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0); /* Send reply and start the thread with the defined CPU register set */ tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) printf("Error sending IPC: %x\n", err); /* Idle around */ while (1) l4_sleep(10000); return 0; }
/* Our main function */ int main(void) { /* Get a capability slot for our new thread. */ l4_cap_idx_t t1 = l4re_util_cap_alloc(); l4_utcb_t *u = l4_utcb(); l4_exc_regs_t *e = l4_utcb_exc_u(u); l4_msgtag_t tag; int err; printf("Example showing how to start a thread with an exception.\n"); /* We do not want to implement a pager here, take the shortcut. */ printf("Make sure to start this program with ldr-flags=eager_map\n"); if (l4_is_invalid_cap(t1)) return 1; /* Create the thread using our default factory */ tag = l4_factory_create_thread(l4re_env()->factory, t1); if (l4_error(tag)) return 1; /* Setup the thread by setting the pager and task. */ l4_thread_control_start(); l4_thread_control_pager(l4re_env()->main_thread); l4_thread_control_exc_handler(l4re_env()->main_thread); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP); tag = l4_thread_control_commit(t1); if (l4_error(tag)) return 2; /* Start the thread by finally setting instruction and stack pointer */ tag = l4_thread_ex_regs(t1, (l4_umword_t)thread, (l4_umword_t)thread_stack + sizeof(thread_stack), L4_THREAD_EX_REGS_TRIGGER_EXCEPTION); if (l4_error(tag)) return 3; l4_sched_param_t sp = l4_sched_param(1, 0); tag = l4_scheduler_run_thread(l4re_env()->scheduler, t1, &sp); if (l4_error(tag)) return 4; /* Receive initial exception from just started thread */ tag = l4_ipc_receive(t1, u, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) { printf("Umm, ipc error: %x\n", err); return 1; } /* We expect an exception IPC */ if (!l4_msgtag_is_exception(tag)) { printf("PF?: %lx %lx (not prepared to handle this) %ld\n", l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag)); return 1; } /* Fill out the complete register set of the new thread */ e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack)); #ifdef ARCH_x86 e->ip = (l4_umword_t)thread; e->eax = 1; e->ebx = 4; e->ecx = 2; e->edx = 3; e->esi = 6; e->edi = 7; e->ebp = 5; #endif #ifdef ARCH_arm e->pc = (l4_umword_t)thread; e->r[0] = 0; e->r[1] = 1; e->r[2] = 2; e->r[3] = 3; e->r[4] = 4; e->r[5] = 5; e->r[6] = 6; e->r[7] = 7; #endif /* Send a complete exception */ tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0); /* Send reply and start the thread with the defined CPU register set */ tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) printf("Error sending IPC: %x\n", err); /* Idle around */ while (1) l4_sleep(10000); return 0; }
int main(dword_t mb_magic, struct multiboot_info *mbi) { CORBA_Environment env = idl4_default_environment; int i,j,msg[8] = { 0,0x6100,0x0100,0,0,0,0,0 }; struct mod_list *mods; l4_msgdope_t result; Elf32_Phdr *phdr; l4_threadid_t msvr; int mobj, pagerid, tobj; int blockID=0; int found_root=0; int totalBlock=0; init_global_data(); printf("Booter task (%x) starting, pager is %X\n", booter.raw, sigma0.raw); check_multiboot_header(mb_magic,&mbi); printf("Multiboot header found at %X\n", (dword_t) mbi); mods = (mod_list*) mbi->mods_addr; secure_modules(mods, (int)mbi->mods_count); launch_aux_pager(); task[0].active=1; task[0].root.svr.raw=0; task[0].root.obj=0; task[0].memory.svr=sigma0; task[0].memory.obj=DEFAULT_OBJECT; strncpy(task[0].cmdline,(char*)mods[BOOTER_MODULE_NR].cmdline,MAXLENGTH); task[0].task_id=booter; task[0].owner=booter; // ************************************************************************* // *** bootup sequence if (mbi->mods_count < (BOOTER_MODULE_NR+2)) enter_kdebug("nothing to load"); mods = (struct mod_list *) mbi->mods_addr; nexttask = booter; (void)nexttask.id.task++; for (j=BOOTER_MODULE_NR+1;j<(int)mbi->mods_count;j++) { Elf32_Ehdr *file_hdr; // *** check sanity of elf file file_hdr = (Elf32_Ehdr *) mods[j].mod_start; if (file_hdr->e_ident[EI_MAG0] != ELFMAG0 || file_hdr->e_ident[EI_MAG1] != ELFMAG1 || file_hdr->e_ident[EI_MAG2] != ELFMAG2 || file_hdr->e_ident[EI_MAG3] != ELFMAG3) { i=0; while ((i<MAXBLOCKS) && (block[i].active)) i++; if (i<MAXBLOCKS) { block[i].active=1; block[i].phys_addr=(int)mods[j].mod_start; block[i].capacity=((int)mods[j].mod_end-(int)mods[j].mod_start)/512; block[i].blocksize=512; totalBlock++; if (found_root) { char name[20]; sprintf(name,"hd%c",'a'+(blockID++)); directory_link(dev.svr,dev.obj,3,name,&booter,MAXTASKS+i,&env); } } continue; } if (file_hdr->e_type != ET_EXEC) enter_kdebug("unexpected e_type"); if (file_hdr->e_machine != EM_386) enter_kdebug("not an intel binary"); if (file_hdr->e_version != EV_CURRENT) enter_kdebug("version mismatch?"); if (file_hdr->e_flags != 0) enter_kdebug("unexpected flags?"); if (file_hdr->e_phnum <= 0) enter_kdebug("No loadable program sections"); // *** create the task. this will map the trampoline code into page 0 // of the newly created address space printf("Task %d: %s\n",(int)nexttask.id.task,(char*)mods[j].cmdline); l4_task_new(nexttask, 255, 0, 0, auxpager); // *** if the memory server is already running, make it the new task's // pager. (should be replaced by dynamic object creation) if (j>(BOOTER_MODULE_NR+1)) { if (creator_create(memsvr,DEFAULT_OBJECT,sizeof(api_mem)/sizeof(int), (sdword*)&api_mem,&msvr,&mobj,&env)!=ESUCCESS) enter_kdebug("Memory object creation failed"); memory_set_maxpages(msvr,mobj,99999999,&env); memory_attach(msvr,mobj,&nexttask,&env); memory_get_pagerid(msvr,mobj,&pagerid,&env); l4_ipc_send(nexttask,0,TRAMPOLINE_NEW_PAGER,pagerid,0,L4_IPC_NEVER,&result); } else { msvr = sigma0;mobj=DEFAULT_OBJECT; } // *** allocate struct for the task tobj=0; while ((tobj<MAXTASKS) && (task[tobj].active)) tobj++; if (tobj==MAXTASKS) enter_kdebug("Too many tasks"); task[tobj].active=1; if (found_root) { task[tobj].root.svr=root.svr; task[tobj].root.obj=root.obj; } else { task[tobj].root.svr.raw=0; task[tobj].root.obj=0; } task[tobj].memory.svr=msvr; task[tobj].memory.obj=mobj; strncpy(task[tobj].cmdline,(char*)mods[j].cmdline,MAXLENGTH); task[tobj].cmdline[MAXLENGTH-1]=0; task[tobj].task_id=nexttask; task[tobj].owner=booter; // *** parse all the headers phdr = (Elf32_Phdr *) (file_hdr->e_phoff + (unsigned int) file_hdr); for (i=0;i<file_hdr->e_phnum;i++) if (phdr[i].p_type == PT_LOAD) { // *** notify the trampoline l4_ipc_send(nexttask,0,TRAMPOLINE_RECEIVE,(int)phdr[i].p_vaddr, (int)phdr[i].p_filesz,L4_IPC_NEVER,&result); msg[6]=(int)phdr[i].p_filesz; msg[7]=(int)file_hdr + phdr[i].p_offset; // *** send the string ipc. this will cause a bunch of pagefaults, // which will be handled by the child's pager #ifdef DEBUG printf("Copying segment of size %x from address %x to %x\n",msg[6],msg[7],(int)phdr[i].p_vaddr); #endif l4_ipc_send(nexttask,&msg,0,0,0,L4_IPC_NEVER,&result); // *** zero out any bss segments if (phdr[i].p_memsz>phdr[i].p_filesz) { int zero_base = phdr[i].p_vaddr+phdr[i].p_filesz; int zero_size = phdr[i].p_memsz-phdr[i].p_filesz; #ifdef DEBUG printf("Erasing zone at %x, size %x\n",zero_base,zero_size); #endif l4_ipc_send(nexttask,0,TRAMPOLINE_ZERO_ZONE, zero_base,zero_size,L4_IPC_NEVER,&result); } } // *** if this is the memory server, change the pager to sigma0 if (j==(BOOTER_MODULE_NR+1)) l4_ipc_send(nexttask,0,TRAMPOLINE_NEW_PAGER,sigma0.raw,0,L4_IPC_NEVER,&result); // *** start the program #ifdef DEBUG printf("Jumping to program entry point at %x [objID=%d]\n\n",(int)file_hdr->e_entry,tobj); #endif l4_ipc_send(nexttask,0,TRAMPOLINE_LAUNCH,tobj,file_hdr->e_entry,L4_IPC_NEVER,&result); // *** wait until thread leaves the trampoline code for (i=0;i<3;i++) l4_thread_switch(nexttask); // *** flush the trampoline l4_fpage_unmap(l4_fpage((int)&_trampoline,L4_LOG2_PAGESIZE,0,0),L4_FP_FLUSH_PAGE); // *** see about the supported interfaces if (j==(BOOTER_MODULE_NR+1)) { memsvr=nexttask; if (generic_implements(nexttask,DEFAULT_OBJECT,sizeof(api_creator)/sizeof(int),(sdword*)&api_creator,&env)!=EYES) enter_kdebug("Memory server does not support Creator API"); if (creator_can_create(nexttask,DEFAULT_OBJECT,sizeof(api_mem)/sizeof(int),(sdword*)&api_mem,&env)!=EYES) enter_kdebug("Memory server cannot create memory objects"); } if (!found_root) if (generic_implements(nexttask,DEFAULT_OBJECT,sizeof(api_creator)/sizeof(int),(sdword*)&api_creator,&env)==EYES) if (creator_can_create(nexttask,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)==EYES) { root.svr=nexttask;found_root=1; #ifdef DEBUG printf("Found root nameserver (%X), creating /...\n",root.svr.raw); #endif if (creator_create(root.svr,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&root.svr,&root.obj,&env)!=ESUCCESS) enter_kdebug("Root directory creation failed"); if (creator_create(root.svr,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&dev.svr,&dev.obj,&env)!=ESUCCESS) enter_kdebug("/dev directory creation failed"); if (generic_implements(root.svr,root.obj,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)!=EYES) enter_kdebug("Defective root directory"); if (directory_link(root.svr,root.obj,3,"dev",&dev.svr,dev.obj,&env)!=ESUCCESS) enter_kdebug("Cannot link dev into /"); if (directory_link(dev.svr,dev.obj,7,"tasksvr",&booter,0,&env)!=ESUCCESS) enter_kdebug("Cannot link tasksvr into /dev/"); for (int i=0;i<MAXBLOCKS;i++) if (block[i].active) { char name[20]; sprintf(name,"hd%c",'a'+(blockID++)); directory_link(dev.svr,dev.obj,3,name,&booter,MAXTASKS+i,&env); } for (int k=0;k<MAXTASKS;k++) if ((task[k].active) && (!task[k].root.svr.raw)) { task[k].root.svr=root.svr; task[k].root.obj=root.obj; } #ifdef DEBUG printf("Root creation completed, all servers notified\n\n"); #endif } (void)nexttask.id.task++; } // *** modify the trampoline to work with elf launcher // *** this is BAD magic! int *m1=(int*)(((int)&_m1)+1); int *m2=(int*)(((int)&_m2)+1); *m1=0x04041001; *m2=0x04041001; if (totalBlock) printf("Created %d block device(s)\n",totalBlock); // *** enter server loop booter_server(); }