Changeset c98e6ee in mainline for kernel/generic/src
- Timestamp:
- 2008-07-08T16:05:45Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f93f168
- Parents:
- b7f9087
- Location:
- kernel/generic/src
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/elf.c
rb7f9087 rc98e6ee 58 58 59 59 static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, 60 as_t *as );60 as_t *as, int flags); 61 61 static int section_header(elf_section_header_t *entry, elf_header_t *elf, 62 62 as_t *as); … … 68 68 * @param header Pointer to ELF header in memory 69 69 * @param as Created and properly mapped address space 70 * @param flags A combination of ELD_F_* 70 71 * @return EE_OK on success 71 72 */ 72 unsigned int elf_load(elf_header_t *header, as_t * as )73 unsigned int elf_load(elf_header_t *header, as_t * as, int flags) 73 74 { 74 75 int i, rc; … … 111 112 seghdr = &((elf_segment_header_t *)(((uint8_t *) header) + 112 113 header->e_phoff))[i]; 113 rc = segment_header(seghdr, header, as );114 rc = segment_header(seghdr, header, as, flags); 114 115 if (rc != EE_OK) 115 116 return rc; … … 152 153 */ 153 154 static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, 154 as_t *as) 155 { 155 as_t *as, int flags) 156 { 157 char *interp; 158 156 159 switch (entry->p_type) { 157 160 case PT_NULL: … … 163 166 case PT_DYNAMIC: 164 167 case PT_INTERP: 168 interp = (char *)elf + entry->p_offset; 169 /* FIXME */ 170 /*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR, 171 ELF_INTERP_ZLEN) != 0) { 172 return EE_UNSUPPORTED; 173 }*/ 174 if ((flags & ELD_F_LOADER) == 0) { 175 return EE_LOADER; 176 } 177 break; 165 178 case PT_SHLIB: 166 179 case PT_NOTE: -
kernel/generic/src/main/kinit.c
rb7f9087 rc98e6ee 48 48 #include <proc/task.h> 49 49 #include <proc/thread.h> 50 #include <proc/program.h> 50 51 #include <panic.h> 51 52 #include <func.h> … … 160 161 */ 161 162 count_t i; 162 thread_t *threads[CONFIG_INIT_TASKS];163 program_t programs[CONFIG_INIT_TASKS]; 163 164 164 165 for (i = 0; i < init.cnt; i++) { … … 168 169 } 169 170 170 threads[i] = thread_create_program((void *) init.tasks[i].addr,171 "uspace");172 173 if ( threads[i]!= NULL) {171 int rc = program_create_from_image((void *) init.tasks[i].addr, 172 &programs[i]); 173 174 if (rc == 0 && programs[i].task != NULL) { 174 175 /* 175 176 * Set capabilities to init userspace tasks. 176 177 */ 177 cap_set( threads[i]->task, CAP_CAP | CAP_MEM_MANAGER |178 cap_set(programs[i].task, CAP_CAP | CAP_MEM_MANAGER | 178 179 CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG); 180 179 181 180 182 if (!ipc_phone_0) 181 ipc_phone_0 = &threads[i]->task->answerbox; 183 ipc_phone_0 = &programs[i].task->answerbox; 184 } else if (rc == 0) { 185 /* It was the program loader and was registered */ 182 186 } else { 187 /* RAM disk image */ 183 188 int rd = init_rd((rd_header_t *) init.tasks[i].addr, 184 189 init.tasks[i].size); … … 194 199 */ 195 200 for (i = 0; i < init.cnt; i++) { 196 if ( threads[i]!= NULL) {201 if (programs[i].task != NULL) { 197 202 thread_usleep(50000); 198 thread_ready(threads[i]);203 program_ready(&programs[i]); 199 204 } 200 205 } -
kernel/generic/src/mm/as.c
rb7f9087 rc98e6ee 772 772 } 773 773 774 /** Change adress area flags. 775 * 776 * The idea is to have the same data, but with a different access mode. 777 * This is needed e.g. for writing code into memory and then executing it. 778 * In order for this to work properly, this may copy the data 779 * into private anonymous memory (unless it's already there). 780 * 781 * @param as Address space. 782 * @param flags Flags of the area memory. 783 * @param address Address withing the area to be changed. 784 * 785 * @return Zero on success or a value from @ref errno.h on failure. 786 */ 787 int as_area_change_flags(as_t *as, int flags, uintptr_t address) 788 { 789 as_area_t *area; 790 uintptr_t base; 791 link_t *cur; 792 ipl_t ipl; 793 int page_flags; 794 uintptr_t *old_frame; 795 index_t frame_idx; 796 count_t used_pages; 797 798 /* Flags for the new memory mapping */ 799 page_flags = area_flags_to_page_flags(flags); 800 801 ipl = interrupts_disable(); 802 mutex_lock(&as->lock); 803 804 area = find_area_and_lock(as, address); 805 if (!area) { 806 mutex_unlock(&as->lock); 807 interrupts_restore(ipl); 808 return ENOENT; 809 } 810 811 if (area->sh_info || area->backend != &anon_backend) { 812 /* Copying shared areas not supported yet */ 813 /* Copying non-anonymous memory not supported yet */ 814 mutex_unlock(&area->lock); 815 mutex_unlock(&as->lock); 816 interrupts_restore(ipl); 817 return ENOTSUP; 818 } 819 820 base = area->base; 821 822 /* 823 * Compute total number of used pages in the used_space B+tree 824 */ 825 used_pages = 0; 826 827 for (cur = area->used_space.leaf_head.next; 828 cur != &area->used_space.leaf_head; cur = cur->next) { 829 btree_node_t *node; 830 unsigned int i; 831 832 node = list_get_instance(cur, btree_node_t, leaf_link); 833 for (i = 0; i < node->keys; i++) { 834 used_pages += (count_t) node->value[i]; 835 } 836 } 837 838 /* An array for storing frame numbers */ 839 old_frame = malloc(used_pages * sizeof(uintptr_t), 0); 840 841 /* 842 * Start TLB shootdown sequence. 843 */ 844 tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages); 845 846 /* 847 * Remove used pages from page tables and remember their frame 848 * numbers. 849 */ 850 frame_idx = 0; 851 852 for (cur = area->used_space.leaf_head.next; 853 cur != &area->used_space.leaf_head; cur = cur->next) { 854 btree_node_t *node; 855 unsigned int i; 856 857 node = list_get_instance(cur, btree_node_t, leaf_link); 858 for (i = 0; i < node->keys; i++) { 859 uintptr_t b = node->key[i]; 860 count_t j; 861 pte_t *pte; 862 863 for (j = 0; j < (count_t) node->value[i]; j++) { 864 page_table_lock(as, false); 865 pte = page_mapping_find(as, b + j * PAGE_SIZE); 866 ASSERT(pte && PTE_VALID(pte) && 867 PTE_PRESENT(pte)); 868 old_frame[frame_idx++] = PTE_GET_FRAME(pte); 869 870 /* Remove old mapping */ 871 page_mapping_remove(as, b + j * PAGE_SIZE); 872 page_table_unlock(as, false); 873 } 874 } 875 } 876 877 /* 878 * Finish TLB shootdown sequence. 879 */ 880 881 tlb_invalidate_pages(as->asid, area->base, area->pages); 882 /* 883 * Invalidate potential software translation caches (e.g. TSB on 884 * sparc64). 885 */ 886 as_invalidate_translation_cache(as, area->base, area->pages); 887 tlb_shootdown_finalize(); 888 889 /* 890 * Map pages back in with new flags. This step is kept separate 891 * so that there's no instant when the memory area could be 892 * accesed with both the old and the new flags at once. 893 */ 894 frame_idx = 0; 895 896 for (cur = area->used_space.leaf_head.next; 897 cur != &area->used_space.leaf_head; cur = cur->next) { 898 btree_node_t *node; 899 unsigned int i; 900 901 node = list_get_instance(cur, btree_node_t, leaf_link); 902 for (i = 0; i < node->keys; i++) { 903 uintptr_t b = node->key[i]; 904 count_t j; 905 906 for (j = 0; j < (count_t) node->value[i]; j++) { 907 page_table_lock(as, false); 908 909 /* Insert the new mapping */ 910 page_mapping_insert(as, b + j * PAGE_SIZE, 911 old_frame[frame_idx++], page_flags); 912 913 page_table_unlock(as, false); 914 } 915 } 916 } 917 918 free(old_frame); 919 920 mutex_unlock(&area->lock); 921 mutex_unlock(&as->lock); 922 interrupts_restore(ipl); 923 924 return 0; 925 } 926 927 774 928 /** Handle page fault within the current address space. 775 929 * … … 1767 1921 } 1768 1922 1923 /** Wrapper for as_area_change_flags(). */ 1924 unative_t sys_as_area_change_flags(uintptr_t address, int flags) 1925 { 1926 return (unative_t) as_area_change_flags(AS, flags, address); 1927 } 1928 1769 1929 /** Wrapper for as_area_destroy(). */ 1770 1930 unative_t sys_as_area_destroy(uintptr_t address) -
kernel/generic/src/proc/task.c
rb7f9087 rc98e6ee 36 36 */ 37 37 38 #include <main/uinit.h>39 38 #include <proc/thread.h> 40 39 #include <proc/task.h> 41 #include <proc/uarg.h>42 40 #include <mm/as.h> 43 41 #include <mm/slab.h> … … 47 45 #include <arch.h> 48 46 #include <arch/barrier.h> 49 #include <panic.h>50 47 #include <adt/avl.h> 51 48 #include <adt/btree.h> 52 49 #include <adt/list.h> 53 50 #include <ipc/ipc.h> 54 #include <security/cap.h> 55 #include <memstr.h> 51 #include <ipc/ipcrsc.h> 56 52 #include <print.h> 57 #include <lib/elf.h>58 53 #include <errno.h> 59 54 #include <func.h> 60 55 #include <syscall/copy.h> 61 62 #ifndef LOADED_PROG_STACK_PAGES_NO63 #define LOADED_PROG_STACK_PAGES_NO 164 #endif65 56 66 57 /** Spinlock protecting the tasks_tree AVL tree. */ … … 252 243 } 253 244 254 unative_t sys_task_spawn(void *image, size_t size)255 {256 void *kimage = malloc(size, 0);257 if (kimage == NULL)258 return ENOMEM;259 260 int rc = copy_from_uspace(kimage, image, size);261 if (rc != EOK)262 return rc;263 264 /*265 * Not very efficient and it would be better to call it on code only,266 * but this whole function is a temporary hack anyway and one day it267 * will go in favor of the userspace dynamic loader.268 */269 smc_coherence_block(kimage, size);270 271 uspace_arg_t *kernel_uarg;272 kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);273 if (kernel_uarg == NULL) {274 free(kimage);275 return ENOMEM;276 }277 278 kernel_uarg->uspace_entry =279 (void *) ((elf_header_t *) kimage)->e_entry;280 kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;281 kernel_uarg->uspace_thread_function = NULL;282 kernel_uarg->uspace_thread_arg = NULL;283 kernel_uarg->uspace_uarg = NULL;284 285 as_t *as = as_create(0);286 if (as == NULL) {287 free(kernel_uarg);288 free(kimage);289 return ENOMEM;290 }291 292 unsigned int erc = elf_load((elf_header_t *) kimage, as);293 if (erc != EE_OK) {294 as_destroy(as);295 free(kernel_uarg);296 free(kimage);297 return ENOENT;298 }299 300 as_area_t *area = as_area_create(as,301 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,302 LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,303 AS_AREA_ATTR_NONE, &anon_backend, NULL);304 if (area == NULL) {305 as_destroy(as);306 free(kernel_uarg);307 free(kimage);308 return ENOMEM;309 }310 311 task_t *task = task_create(as, "app");312 if (task == NULL) {313 as_destroy(as);314 free(kernel_uarg);315 free(kimage);316 return ENOENT;317 }318 319 // FIXME: control the capabilities320 cap_set(task, cap_get(TASK));321 322 thread_t *thread = thread_create(uinit, kernel_uarg, task,323 THREAD_FLAG_USPACE, "user", false);324 if (thread == NULL) {325 task_destroy(task);326 as_destroy(as);327 free(kernel_uarg);328 free(kimage);329 return ENOENT;330 }331 332 thread_ready(thread);333 334 return EOK;335 }336 337 245 /** Find task structure corresponding to task ID. 338 246 * -
kernel/generic/src/proc/thread.c
rb7f9087 rc98e6ee 673 673 } 674 674 675 676 /** Create new user task with 1 thread from image677 *678 * @param program_addr Address of program executable image.679 * @param name Program name.680 *681 * @return Initialized main thread of the task or NULL on error.682 */683 thread_t *thread_create_program(void *program_addr, char *name)684 {685 as_t *as;686 as_area_t *area;687 unsigned int rc;688 task_t *task;689 uspace_arg_t *kernel_uarg;690 691 kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);692 if (kernel_uarg == NULL)693 return NULL;694 695 kernel_uarg->uspace_entry =696 (void *) ((elf_header_t *) program_addr)->e_entry;697 kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;698 kernel_uarg->uspace_thread_function = NULL;699 kernel_uarg->uspace_thread_arg = NULL;700 kernel_uarg->uspace_uarg = NULL;701 702 as = as_create(0);703 if (as == NULL) {704 free(kernel_uarg);705 return NULL;706 }707 708 rc = elf_load((elf_header_t *) program_addr, as);709 if (rc != EE_OK) {710 free(kernel_uarg);711 as_destroy(as);712 return NULL;713 }714 715 /*716 * Create the data as_area.717 */718 area = as_area_create(as,719 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,720 LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,721 AS_AREA_ATTR_NONE, &anon_backend, NULL);722 if (area == NULL) {723 free(kernel_uarg);724 as_destroy(as);725 return NULL;726 }727 728 task = task_create(as, name);729 if (task == NULL) {730 free(kernel_uarg);731 as_destroy(as);732 return NULL;733 }734 735 /*736 * Create the main thread.737 */738 return thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,739 "uinit", false);740 }741 742 743 675 /** Update accounting of current thread. 744 676 * -
kernel/generic/src/syscall/syscall.c
rb7f9087 rc98e6ee 39 39 #include <proc/thread.h> 40 40 #include <proc/task.h> 41 #include <proc/program.h> 41 42 #include <mm/as.h> 42 43 #include <print.h> … … 47 48 #include <ipc/sysipc.h> 48 49 #include <synch/futex.h> 50 #include <synch/smc.h> 49 51 #include <ddi/ddi.h> 50 52 #include <security/cap.h> … … 124 126 125 127 (syshandler_t) sys_task_get_id, 126 (syshandler_t) sys_ task_spawn,128 (syshandler_t) sys_program_spawn_loader, 127 129 128 130 /* Synchronization related syscalls. */ 129 131 (syshandler_t) sys_futex_sleep_timeout, 130 132 (syshandler_t) sys_futex_wakeup, 133 (syshandler_t) sys_smc_coherence, 131 134 132 135 /* Address space related syscalls. */ 133 136 (syshandler_t) sys_as_area_create, 134 137 (syshandler_t) sys_as_area_resize, 138 (syshandler_t) sys_as_area_change_flags, 135 139 (syshandler_t) sys_as_area_destroy, 136 140
Note:
See TracChangeset
for help on using the changeset viewer.