/**************************************************************************** * fs/mmap/fs_munmap.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "inode/inode.h" #include "fs_rammap.h" #include "sched/sched.h" /**************************************************************************** * Private Functions ****************************************************************************/ static int file_munmap_(FAR void *start, size_t length, enum mm_map_type_e type) { FAR struct tcb_s *tcb = this_task(); FAR struct task_group_s *group = tcb->group; FAR struct mm_map_entry_s *entry = NULL; FAR struct mm_map_s *mm = get_current_mm(); int ret = OK; /* Iterate through all the mappings and call the underlying * unmap for every mapping where "start" lies * break loop on any errors. * * Get exclusive access to mm_map for this */ ret = mm_map_lock(); if (ret == OK) { entry = mm_map_find(mm, start, length); /* If entry don't find, the start and length is invalid. */ if (entry == NULL) { ret = -EINVAL; goto unlock; } do { DEBUGASSERT(entry->munmap); ret = entry->munmap(group, entry, start, length); } while (ret == OK && (entry = mm_map_find(mm, start, length))); unlock: mm_map_unlock(); } return ret; } /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: file_mummap * * Description: * Equivalent to the standard file_mummap() function except it does not set * the errno variable. * ****************************************************************************/ int file_munmap(FAR void *start, size_t length) { return file_munmap_(start, length, MAP_KERNEL); } /**************************************************************************** * Name: munmap * * Description: * * munmap() system call deletes mappings for the specified address range. * All memory starting with 'start' and continuing for a length of 'length' * bytes are removed. * * NuttX operates in a flat open address space. Therefore, it generally * does not require mmap() and, hence, munmap functionality. There are * two exceptions where mmap() is available: * * 1. mmap() is the API that is used to support direct access to random * access media under the following very restrictive conditions: * * a. The filesystem implements the mmap file operation. Any file * system that maps files contiguously on the media should support * this ioctl. (vs. file system that scatter files over the media * in non-contiguous sectors). As of this writing, ROMFS is the * only file system that meets this requirement. * b. The underlying block driver supports the BIOC_XIPBASE ioctl * command that maps the underlying media to a randomly accessible * address. At present, only the RAM/ROM disk driver does this. * * munmap() is still not required in this first case. The mapped address * is a static address in the MCUs address space does not need to be * munmapped. Support for munmap() in this case provided by the simple * definition in sys/mman.h: * * #define munmap(start, length) * * 2. If CONFIG_FS_RAMMAP is defined in the configuration, then mmap() will * support simulation of memory mapped files by copying files whole * into RAM. munmap() is required in this case to free the allocated * memory holding the shared copy of the file. * * Input Parameters: * start The start address of the mapping to delete. For this * simplified munmap() implementation, the must be the start * address of the memory region (the same address returned by * mmap()). * length The length region to be unmapped. * * Returned Value: * On success, munmap() returns 0, on failure -1, and errno is set * (probably to EINVAL). * ****************************************************************************/ int munmap(FAR void *start, size_t length) { int ret; ret = file_munmap_(start, length, MAP_USER); if (ret < 0) { set_errno(-ret); ret = ERROR; } return ret; }