int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize, size_t datasize, size_t heapsize) { #ifdef CONFIG_ARCH_ADDRENV FAR void *vtext; FAR void *vdata; int ret; /* Create an address environment for the new ELF task */ ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv); if (ret < 0) { bdbg("ERROR: up_addrenv_create failed: %d\n", ret); return ret; } /* Get the virtual address associated with the start of the address * environment. This is the base address that we will need to use to * access the ELF image (but only if the address environment has been * selected. */ ret = up_addrenv_vtext(&loadinfo->addrenv, &vtext); if (ret < 0) { bdbg("ERROR: up_addrenv_vtext failed: %d\n", ret); return ret; } ret = up_addrenv_vdata(&loadinfo->addrenv, textsize, &vdata); if (ret < 0) { bdbg("ERROR: up_adup_addrenv_vdatadrenv_vtext failed: %d\n", ret); return ret; } loadinfo->textalloc = (uintptr_t)vtext; loadinfo->dataalloc = (uintptr_t)vdata; return OK; #else /* Allocate memory to hold the ELF image */ loadinfo->textalloc = (uintptr_t)kumm_zalloc(textsize + datasize); if (!loadinfo->textalloc) { return -ENOMEM; } loadinfo->dataalloc = loadinfo->textalloc + textsize; return OK; #endif }
FAR DIR *opendir(FAR const char *path) { FAR struct inode *inode = NULL; FAR struct fs_dirent_s *dir; struct inode_search_s desc; #ifndef CONFIG_DISABLE_MOUNTPOINT FAR const char *relpath = NULL; #endif bool isroot = false; int ret; /* If we are given 'nothing' then we will interpret this as * request for the root inode. */ SETUP_SEARCH(&desc, path, false); inode_semtake(); if (path == NULL || *path == '\0' || strcmp(path, "/") == 0) { inode = g_root_inode; isroot = true; } else { /* We don't know what to do with relative pathes */ if (*path != '/') { ret = -ENOTDIR; goto errout_with_semaphore; } /* Find the node matching the path. */ ret = inode_search(&desc); if (ret >= 0) { inode = desc.node; DEBUGASSERT(inode != NULL); #ifndef CONFIG_DISABLE_MOUNTPOINT relpath = desc.relpath; #endif } } /* Did we get an inode? */ if (inode == NULL) { /* Inode for 'path' does not exist. */ ret = ENOTDIR; goto errout_with_semaphore; } /* Allocate a type DIR -- which is little more than an inode * container. */ dir = (FAR struct fs_dirent_s *)kumm_zalloc(sizeof(struct fs_dirent_s)); if (!dir) { /* Insufficient memory to complete the operation. */ ret = ENOMEM; goto errout_with_semaphore; } /* Populate the DIR structure and return it to the caller. The way that * we do this depends on whenever this is a "normal" pseudo-file-system * inode or a file system mountpoint. */ dir->fd_position = 0; /* This is the position in the read stream */ /* First, handle the special case of the root inode. This must be * special-cased here because the root inode might ALSO be a mountpoint. */ if (isroot) { /* Whatever payload the root inode carries, the root inode is always * a directory inode in the pseudo-file system */ open_pseudodir(inode, dir); } /* Is this a node in the pseudo filesystem? Or a mountpoint? If the node * is the root (isroot == TRUE), then this is a special case. */ #ifndef CONFIG_DISABLE_MOUNTPOINT else if (INODE_IS_MOUNTPT(inode)) { /* Yes, the node is a file system mountpoint */ dir->fd_root = inode; /* Save the inode where we start */ /* Open the directory at the relative path */ ret = open_mountpoint(inode, relpath, dir); if (ret != OK) { goto errout_with_direntry; } } #endif else { /* The node is part of the root pseudo file system. Does the inode * have a child? If so that the child would be the 'root' of a list * of nodes under the directory. */ FAR struct inode *child = inode->i_child; if (child != NULL) { /* It looks we have a valid pseudo-filesystem directory node. */ open_pseudodir(child, dir); } else if (!inode->u.i_ops) { /* This is a dangling node with no children and no operations. Set * up to enumerate an empty directory. */ open_emptydir(dir); } else { ret = ENOTDIR; goto errout_with_direntry; } } RELEASE_SEARCH(&desc); inode_semgive(); return ((FAR DIR *)dir); /* Nasty goto's make error handling simpler */ errout_with_direntry: kumm_free(dir); errout_with_semaphore: RELEASE_SEARCH(&desc); inode_semgive(); set_errno(ret); return NULL; }
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* Is there already a stack allocated of a different size? Because of * alignment issues, stack_size might erroneously appear to be of a * different size. Fortunately, this is not a critical operation. */ if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) { /* Yes.. Release the old stack */ up_release_stack(tcb, ttype); } /* Do we need to allocate a new stack? */ if (!tcb->stack_alloc_ptr) { /* Allocate the stack. If DEBUG is enabled (but not stack debug), * then create a zeroed stack to make stack dumps easier to trace. */ #if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Use the kernel allocator if this is a kernel thread */ if (ttype == TCB_FLAG_TTYPE_KERNEL) { #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK) tcb->stack_alloc_ptr = (uint32_t *)kmm_zalloc(stack_size); #else tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); #endif } else #endif { /* Use the user-space allocator if this is a task or pthread */ #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK) tcb->stack_alloc_ptr = (uint32_t *)kumm_zalloc(stack_size); #else tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); #endif } #ifdef CONFIG_DEBUG /* Was the allocation successful? */ if (!tcb->stack_alloc_ptr) { sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); } #endif } /* Did we successfully allocate a stack? */ if (tcb->stack_alloc_ptr) { size_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. */ #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK) memset(tcb->stack_alloc_ptr, 0xaa, stack_size); #endif /* The i486 uses a push-down stack: the stack grows toward lower * addresses in memory. The stack pointer register, points to the * lowest, valid work address (the "top" of the stack). Items on * the stack are referenced as positive word offsets from sp. */ top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; /* The i486 stack must be aligned at word (4 byte) boundaries. If * necessary top_of_stack must be rounded down to the next boundary */ top_of_stack &= ~3; size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the struct tcb_s */ tcb->adj_stack_ptr = (uint32_t*)top_of_stack; tcb->adj_stack_size = size_of_stack; board_led_on(LED_STACKCREATED); return OK; } return ERROR; }
int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize) { FAR struct dspace_s *dspace; #ifdef CONFIG_ARCH_ADDRENV FAR void *vdata; save_addrenv_t oldenv; size_t heapsize; int ret; #endif DEBUGASSERT(!loadinfo->dspace); /* Allocate the struct dspace_s container for the D-Space allocation */ dspace = (FAR struct dspace_s *)kmm_malloc(sizeof(struct dspace_s)); if (dspace == 0) { bdbg("ERROR: Failed to allocate DSpace\n"); return -ENOMEM; } #ifdef CONFIG_ARCH_ADDRENV /* Determine the heapsize to allocate. If there is no dynamic stack then * heapsize must at least as big as the fixed stack size since the stack * will be allocated from the heap in that case. */ #ifdef CONFIG_ARCH_STACK_DYNAMIC heapsize = ARCH_HEAP_SIZE; #else heapsize = MIN(loadinfo->stacksize, ARCH_HEAP_SIZE); #endif /* Create a D-Space address environment for the new NXFLAT task */ ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv); if (ret < 0) { bdbg("ERROR: up_addrenv_create failed: %d\n", ret); goto errout_with_dspace; } /* Get the virtual address associated with the start of the address * environment. This is the base address that we will need to use to * access the D-Space region (but only if the address environment has been * selected. */ ret = up_addrenv_vdata(&loadinfo->addrenv, 0, &vdata); if (ret < 0) { bdbg("ERROR: up_addrenv_vdata failed: %d\n", ret); goto errout_with_addrenv; } /* Clear all of the allocated D-Space memory. We have to temporarily * selected the D-Space address environment to do this. */ ret = up_addrenv_select(loadinfo->addrenv, &oldenv); if (ret < 0) { bdbg("ERROR: up_addrenv_select failed: %d\n", ret); goto errout_with_addrenv; } memset(vdata, 0, envsize); ret = up_addrenv_restore(oldenv); if (ret < 0) { bdbg("ERROR: up_addrenv_restore failed: %d\n", ret); goto errout_with_addrenv; } /* Success... save the fruits of our labor */ loadinfo->dspace = dspace; dspace->crefs = 1; dspace->region = (FAR uint8_t *)vdata; return OK; errout_with_addrenv: (void)up_addrenv_destroy(&loadinfo->addrenv); loadinfo->addrenv = 0; errout_with_dspace: kmm_free(dspace); return ret; #else /* Allocate (and zero) memory to hold the ELF image */ dspace->region = (FAR uint8_t *)kumm_zalloc(envsize); if (!dspace->region) { kmm_free(dspace); return -ENOMEM; } loadinfo->dspace = dspace; dspace->crefs = 1; return OK; #endif }