summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-05-08 14:42:42 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-05-08 14:42:42 +0000
commit4a4fd3e2889ad9b3baa0a0c50eea39f5801cdb97 (patch)
tree1607a8e3544808fc3a506a2b946916d91b08f796
parente8d18c24acb47a98f03a1be7e121fcd6398a2d68 (diff)
Complets ram mapping logic
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3578 7fd9a85b-ad96-42d3-883c-3090e2eb8679
-rw-r--r--nuttx/Documentation/NuttXNxFlat.html10
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html7
-rw-r--r--nuttx/Documentation/NuttxUserGuide.html198
-rwxr-xr-xnuttx/Documentation/README.html4
-rwxr-xr-xnuttx/README.txt2
-rw-r--r--nuttx/configs/README.txt3
-rwxr-xr-xnuttx/fs/mmap/README.txt78
-rw-r--r--nuttx/fs/mmap/fs_mmap.c30
-rw-r--r--nuttx/fs/mmap/fs_munmap.c71
-rw-r--r--nuttx/fs/mmap/fs_rammap.c68
-rw-r--r--nuttx/fs/mmap/fs_rammap.h42
-rw-r--r--nuttx/include/sys/mman.h9
12 files changed, 404 insertions, 118 deletions
diff --git a/nuttx/Documentation/NuttXNxFlat.html b/nuttx/Documentation/NuttXNxFlat.html
index b08b658016..d6ada4e9b7 100644
--- a/nuttx/Documentation/NuttXNxFlat.html
+++ b/nuttx/Documentation/NuttXNxFlat.html
@@ -10,7 +10,7 @@
<td>
<h1><big><font color="#3c34ec"><i>NXFLAT</i></font></big></h1>
<h2><font color="#dc143c">&gt;&gt;&gt; Under Construction &lt;&lt;&lt;</font></h2>
- <p>Last Updated: March 20, 2011</p>
+ <p>Last Updated: May 8, 2011</p>
</td>
</tr>
</table>
@@ -193,10 +193,12 @@
<a name="limitations"><h2>1.3 Limitations</h2></a>
<ul>
- <li><b>ROMFS Only</b>.
- The initial NXFLAT release will work only with executable modules residing on a ROMFS
- file system.
+ <li><b>ROMFS (or RAM maps) Only</b>.
+ The initial NXFLAT release will work only with wither (1) executable modules residing on a ROMFS
+ file system, or (2) executables provided on other file systems provided that <code>CONFIG_FS_RAMMAP</code>
+ is defined.
That is because the loader depends on the capability to <code>mmap()</code> the code segment.
+ See the <a href="NuttxUserGuide.html#mmapxip">NuttX User Guide</a> for further information.
NUTTX does not provide any general kind of file mapping capability.
In fact, <i>true </i>file mapping is only possible with RTOSs and MCUs that provide an MMU<sup>1</sup>
and only ROMFS supports that kind of XIP execution from FLASH.
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index 70bdab5379..8d237f8de5 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -12,7 +12,7 @@
<h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i>
</font></big></h1>
- <p>Last Updated: May 6, 2011</p>
+ <p>Last Updated: May 8, 2011</p>
</td>
</tr>
</table>
@@ -3480,6 +3480,11 @@ build
<li>
<code>CONFIG_FS_ROMFS</code>: Enable ROMFS file system support
</li>
+ <li>
+ <code>CONFIG_FS_RAMMAP</code>: For file systems that do not support
+ XIP, this option will enable a limited form of memory mapping that is
+ implemented by copying whole files into memory.
+ </li>
</ul>
<h2>Device Drivers</h2>
diff --git a/nuttx/Documentation/NuttxUserGuide.html b/nuttx/Documentation/NuttxUserGuide.html
index 53bdad919d..8e97173114 100644
--- a/nuttx/Documentation/NuttxUserGuide.html
+++ b/nuttx/Documentation/NuttxUserGuide.html
@@ -13,7 +13,7 @@
<h1><big><font color="#3c34ec"><i>NuttX Operating System<p>User's Manual</i></font></big></h1>
<p><small>by</small></p>
<p>Gregory Nutt<p>
- <p>Last Updated: December 13, 2009</p>
+ <p>Last Updated: May 8, 2011</p>
</td>
</tr>
</table>
@@ -747,10 +747,10 @@ interface of the same name.
priority of the calling task is set.
</li>
<li>
- <I>policy</I>. Scheduling policy requested (either SCHED_FIFO or SCHED_RR).
+ <I>policy</I>. Scheduling policy requested (either <code>SCHED_FIFO</code> or <code>SCHED_RR</code>).
</li>
<li>
- <code>param<code>. A structure whose member sched_priority is the
+ <code>param</code>. A structure whose member sched_priority is the
integer priority. The range of valid priority numbers is from
SCHED_PRIORITY_MIN through SCHED_PRIORITY_MAX.
</li>
@@ -1213,7 +1213,7 @@ of the same name.
<p>
<b>Description:</b> This function removes the message queue named
by &quot;mqName.&quot; If one or more tasks have the message queue
-open when mq_unlink() is called, removal of the message queue
+open when <code>mq_unlink()</code> is called, removal of the message queue
is postponed until all references to the message queue have been
closed.
<p>
@@ -1341,7 +1341,7 @@ interface of the same name.
</p>
<p>
If the message queue is full, and the timeout has already expired by the time
- of the call, <code>mq_timedsend()<code> returns immediately.
+ of the call, <code>mq_timedsend()</code> returns immediately.
</p>
<p>
<b>Input Parameters:</b>
@@ -1483,8 +1483,8 @@ interface of the same name.
priority that has waited the longest will be unblocked.
</p>
<p>
- <code>mq_timedreceive()</code> behaves just like <code>mq_receive()<code>, except
- that if the queue is empty and the <code>O_NONBLOCK<c/ode> flag is not enabled
+ <code>mq_timedreceive()</code> behaves just like <code>mq_receive()</code>, except
+ that if the queue is empty and the <code>O_NONBLOCK</code> flag is not enabled
for the message queue description, then <code>abstime</code> points to a structure
which specifies a ceiling on the time for which the call will block.
This ceiling is an absolute timeout in seconds and nanoseconds since the Epoch
@@ -2681,7 +2681,7 @@ VxWorks provides the following comparable interface:
the location referenced by <code>timerid</code>, a timer ID of type timer_t used to identify
the timer in timer requests.
This timer ID is unique until the timer is deleted.
- The particular clock, <code>clock_id<code>, is defined in <code>&lt;time.h&gt;<code>.
+ The particular clock, <code>clock_id</code>, is defined in <code>&lt;time.h&gt;</code>.
The timer whose ID is returned will be in a disarmed state upon return from
<code>timer_create()</code>.
</p>
@@ -4425,7 +4425,7 @@ interface of the same name.
<p>
The policy parameter may have the value <code>SCHED_FIFO</code> or <code>SCHED_RR</code>
(<code>SCHED_OTHER</code> and <code>SCHED_SPORADIC</code>, in particular, are not supported).
- The <code>SCHED_FIFO</code> and <code>SCHED_RR<code> policies will have a single
+ The <code>SCHED_FIFO</code> and <code>SCHED_RR</code> policies will have a single
scheduling parameter, <code>sched_priority</code>.
</p>
<p>
@@ -4502,8 +4502,8 @@ interface of the same name.
<li>
<code>policy</code>.
The new scheduling policy of the thread.
- Either <code>SCHED_FIFO</code> or <code>SCHED_RR<code>.
- <code>SCHED_OTHER<code> and <code>SCHED_SPORADIC<code> are not supported.
+ Either <code>SCHED_FIFO</code> or <code>SCHED_RR</code>.
+ <code>SCHED_OTHER</code> and <code>SCHED_SPORADIC</code> are not supported.
</li>
<li>
<code>param</code>.
@@ -5141,7 +5141,7 @@ interface of the same name.
<b>Input Parameters:</b>
<p>
<ul>
- <li><code>param<code>.</li>
+ <li><code>mutex</code>.</li>
</ul>
<p>
<b>Returned Values:</b>
@@ -6233,7 +6233,7 @@ interface of the same name.
</p>
<ul>
<li><code>CONFIG_NET_TCPBACKLOG</code>
- Incoming connections pend in a backlog until <code>accept()</cod> is called.
+ Incoming connections pend in a backlog until <code>accept()</code> is called.
The size of the backlog is selected when <code>listen()</code> is called.</li>
</ul>
<p>
@@ -6505,7 +6505,7 @@ void *memmove(void *dest, const void *src, size_t count);
<li><code>pathname</code>.
The full path to the FIFO instance to attach to or to create (if not already created).
</li>
- <li><code>mode<code>.
+ <li><code>mode</code>.
Ignored for now
</li>
</ul>
@@ -6599,26 +6599,132 @@ struct fat_format_s
<h3><a name="mmapxip">2.11.9 <code>mmap()</code> and eXecute In Place (XIP)</a></h3>
<p>
- NuttX operates in a flat open address space.
- Therefore, it generally does not require <code>mmap()</code> functionality.
- There is one one exception:
- <code>mmap()</code> is the API that is used to support direct access to random
- access media under the following very restrictive conditions:
- <ol>
- <li>
- The file-system supports the <code>FIOC_MMAP</code> ioctl command.
- Any file system that maps files contiguously on the media should support this
- <code>ioctl</code> command.
- By comparison, most file system scatter files over the media in non-contiguous
- sectors. As of this writing, ROMFS is the only file system that meets this requirement.
- </li>
- <li>
- The underlying block driver supports the <code>BIOC_XIPBASE</code> <code>ioctl</code> command
- that maps the underlying media to a randomly accessible address.
- At present, only the RAM/ROM disk driver does this.
- </li>
- </ol>
+ NuttX operates in a flat open address space and is focused on MCUs that do
+ support Memory Management Units (MMUs). Therefore, NuttX generally does not
+ require <code>mmap()</code> functionality and the MCUs generally cannot support true
+ memory-mapped files.
+</p>
+<p>
+ However, memory mapping of files is the mechanism used by NXFLAT, the NuttX
+ tiny binary format, to get files into memory in order to execute them.
+ <code>mmap()</code> support is therefore required to support NXFLAT.
+ There are two conditions where <code>mmap()</code> can be supported:
</p>
+<ol type="1">
+ <li>
+ <p>
+ <code>mmap()</code> can be used to support <i>eXecute In Place</i> (XIP) on random access media
+ under the following very restrictive conditions:
+ </p>
+ <ol type="a">
+ <li>
+ <p>
+ The file-system supports the <code>FIOC_MMAP</code> ioctl command.
+ Any file system that maps files contiguously on the media should support this
+ <code>ioctl</code> command.
+ By comparison, most file system scatter files over the media in non-contiguous
+ sectors. As of this writing, ROMFS is the only file system that meets this requirement.
+ </p>
+ </li>
+ <li>
+ <p>
+ The underlying block driver supports the <code>BIOC_XIPBASE</code> <code>ioctl</code> command
+ that maps the underlying media to a randomly accessible address.
+ At present, only the RAM/ROM disk driver does this.
+ </p>
+ </li>
+ </ol>
+ <p>
+ Some limitations of this approach are as follows:
+ <p>
+ <ol type="a">
+ <li>
+ <p>
+ Since no real mapping occurs, all of the file contents are &quot;mapped&quot; into memory.
+ </p>
+ </li>
+ <li>
+ <p>
+ All mapped files are read-only.
+ </p>
+ </li>
+ <li>
+ <p>
+ There are no access privileges.
+ </p>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ If <code>CONFIG_FS_RAMMAP</code> is defined in the configuration, then <code>mmap()</code> will
+ support simulation of memory mapped files by copying files whole into RAM.
+ These copied files have some of the properties of standard memory mapped files.
+ There are many, many exceptions exceptions, however.
+ Some of these include:
+ </p>
+ <ol type="a">
+ <li>
+ <p>
+ The goal is to have a single region of memory that represents a single
+ file and can be shared by many threads. That is, given a filename a
+ thread should be able to open the file, get a file descriptor, and
+ call <code>mmap()</code> to get a memory region. Different file descriptors opened
+ with the same file path should get the same memory region when mapped.
+ </p>
+ <p>
+ The limitation in the current design is that there is insufficient
+ knowledge to know that these different file descriptors correspond to
+ the same file. So, for the time being, a new memory region is created
+ each time that <code>rammmap()</code> is called. Not very useful!
+ </p>
+ </li>
+ <li>
+ <p>
+ The entire mapped portion of the file must be present in memory.
+ Since it is assumed the the MCU does not have an MMU, on-demanding
+ paging in of file blocks cannot be supported. Since the while mapped
+ portion of the file must be present in memory, there are limitations
+ in the size of files that may be memory mapped (especially on MCUs
+ with no significant RAM resources).
+ </p>
+ </li>
+ <li>
+ <p>
+ All mapped files are read-only. You can write to the in-memory image,
+ but the file contents will not change.
+ </p>
+ </li>
+ <li>
+ <p>
+ There are no access privileges.
+ </p>
+ </li>
+ <li>
+ <p>
+ Since there are no processes in NuttX, all <code>mmap()</code> and <code>munmap()</code>
+ operations have immediate, global effects. Under Linux, for example,
+ <code>munmap()</code> would eliminate only the mapping with a process; the mappings
+ to the same file in other processes would not be effected.
+ </p>
+ </li>
+ <li>
+ <p>
+ Like true mapped file, the region will persist after closing the file
+ descriptor. However, at present, these ram copied file regions are
+ <i>not</i> automatically &quot;unmapped&quot; (i.e., freed) when a thread is terminated.
+ This is primarily because it is not possible to know how many users
+ of the mapped region there are and, therefore, when would be the
+ appropriate time to free the region (other than when munmap is called).
+ </p>
+ <p>
+ NOTE: Note, if the design limitation of a) were solved, then it would be
+ easy to solve exception d) as well.
+ </p>
+ </li>
+ </ol>
+ </li>
+</ol>
<h3><a name="mmap">2.11.9.1 <code>mmap</code></a></h3>
<p>
@@ -6952,7 +7058,7 @@ Those socket APIs are discussed in the following paragraphs.</p>
To accept connections, a socket is first created with <code>socket()</code>, a
willingness to accept incoming connections and a queue limit for incoming
connections are specified with <code>listen()</code>, and then the connections are
- accepted with <code>accept()</code>. The <code>listen()</coe> call applies only to sockets of
+ accepted with <code>accept()</code>. The <code>listen()</code> call applies only to sockets of
type <code>SOCK_STREAM</code> or <code>SOCK_SEQPACKET</code>.
</p>
<p>
@@ -7280,11 +7386,11 @@ Those socket APIs are discussed in the following paragraphs.</p>
<b>Input Parameters:</b>
</p>
<ul>
- <li><code>sockfd</code>: Socket descriptor of socket
- <li><code>level</code>: Protocol level to set the option
- <li><code>option</code>: identifies the option to set
- <li><code>value</code>: Points to the argument value
- <li><code>value_len</code>: The length of the argument value
+ <li><code>sockfd</code>: Socket descriptor of socket</li>
+ <li><code>level</code>: Protocol level to set the option</li>
+ <li><code>option</code>: identifies the option to set</li>
+ <li><code>value</code>: Points to the argument value</li>
+ <li><code>value_len</code>: The length of the argument value</li>
</ul>
<p>
<b>Returned Values:</b>
@@ -7337,17 +7443,17 @@ Those socket APIs are discussed in the following paragraphs.</p>
SOL_SOCKET.
</p>
<p>
- See <code>sys/socket.h</code>for a complete list of values for the <code>option</code> argument.
+ See <code>sys/socket.h</code> for a complete list of values for the <code>option</code> argument.
</p>
<p>
<b>Input Parameters:</b>
</p>
<ul>
- <li><code>sockfd Socket descriptor of socket
- <li><code>level Protocol level to set the option
- <li><code>option identifies the option to get
- <li><code>value Points to the argument value
- <li><code>value_len The length of the argument value
+ <li><code>sockfd</code>: Socket descriptor of socket
+ <li><code>level</code>: Protocol level to set the option
+ <li><code>option</code>: Identifies the option to get
+ <li><code>value</code>: Points to the argument value
+ <li><code>value_len</code>: The length of the argument value
</ul>
<p>
<b>Returned Values:</b>
@@ -7364,7 +7470,7 @@ Those socket APIs are discussed in the following paragraphs.</p>
The <code>option</code> is not supported by the protocol.</li>
<li><code>NOTSOCK</code>.
The <code>sockfd</code> argument does not refer to a socket.</li>
- <li><code>NOBUFS
+ <li><code>NOBUFS</code>.
Insufficient resources are available in the system to complete the call.</li>
</ul>
diff --git a/nuttx/Documentation/README.html b/nuttx/Documentation/README.html
index 5c7a89c042..bb07b883a6 100755
--- a/nuttx/Documentation/README.html
+++ b/nuttx/Documentation/README.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX README Files</i></font></big></h1>
- <p>Last Updated: April 15, 2010</p>
+ <p>Last Updated: May 7, 2010</p>
</td>
</tr>
</table>
@@ -167,6 +167,8 @@
| |- drivers/
| | `- <a href="http://nuttx.svn.sourceforge.net/viewvc/nuttx/trunk/nuttx/drivers/README.txt?view=log"><b><i>README.txt</i></b></a>
| |- fs/
+ | | |- mmap/
+ | | | `- <a href="http://nuttx.svn.sourceforge.net/viewvc/nuttx/trunk/nuttx/fs/mmap/README.txt?view=log"><b><i>README.txt</i></b></a>
| | `- nxffs/
| | `- <a href="http://nuttx.svn.sourceforge.net/viewvc/nuttx/trunk/nuttx/fs/nxffs/README.txt?view=log"><b><i>README.txt</i></b></a>
| |- graphics/
diff --git a/nuttx/README.txt b/nuttx/README.txt
index 240f626eef..14d199d9be 100755
--- a/nuttx/README.txt
+++ b/nuttx/README.txt
@@ -416,6 +416,8 @@ Below is a guide to the available README files in the NuttX source tree:
| |- pashello/README.txt
| `- README.txt
|- fs/
+ | |- mmap/
+ | | `- README.txt
| `- nxffs/
| `- README.txt
|- graphics/
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index 8f6438ba7c..82d83eaf2c 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -540,6 +540,9 @@ defconfig -- This is a configuration file similar to the Linux
and making it available for re-use (and possible over-wear).
Default: 8192.
CONFIG_FS_ROMFS - Enable ROMFS filesystem support
+ CONFIG_FS_RAMMAP - For file systems that do not support XIP, this
+ option will enable a limited form of memory mapping that is
+ implemented by copying whole files into memory.
SPI driver
CONFIG_SPI_OWNBUS - Set if there is only one active device
diff --git a/nuttx/fs/mmap/README.txt b/nuttx/fs/mmap/README.txt
new file mode 100755
index 0000000000..cf4c51e9e8
--- /dev/null
+++ b/nuttx/fs/mmap/README.txt
@@ -0,0 +1,78 @@
+fs/mmap README File
+===================
+
+NuttX operates in a flat open address space and is focused on MCUs that do
+support Memory Management Units (MMUs). Therefore, NuttX generally does not
+require mmap() functionality and the MCUs generally cannot support true
+memory-mapped files.
+
+However, memory mapping of files is the mechanism used by NXFLAT, the NuttX
+tiny binary format, to get files into memory in order to execute them.
+mmap() support is therefore required to support NXFLAT. There are two
+conditions where mmap() can be supported:
+
+1. mmap can be used to support eXecute In Place (XIP) on random access media
+ under the following very restrictive conditions:
+
+ a. The filesystem supports the FIOC_MMAP ioctl command. 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.
+
+ Some limitations of this approach are as follows:
+
+ a. Since no real mapping occurs, all of the file contents are "mapped"
+ into memory.
+
+ b. All mapped files are read-only.
+
+ c. There are no access privileges.
+
+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. These copied files have some of the properties of
+ standard memory mapped files. There are many, many exceptions
+ exceptions, however. Some of these include:
+
+ a. The goal is to have a single region of memory that represents a single
+ file and can be shared by many threads. That is, given a filename a
+ thread should be able to open the file, get a file descriptor, and
+ call mmap() to get a memory region. Different file descriptors opened
+ with the same file path should get the same memory region when mapped.
+
+ The limitation in the current design is that there is insufficient
+ knowledge to know that these different file descriptors correspond to
+ the same file. So, for the time being, a new memory region is created
+ each time that rammap() is called. Not very useful!
+
+ b. The entire mapped portion of the file must be present in memory.
+ Since it is assumed the the MCU does not have an MMU, on-demanding
+ paging in of file blocks cannot be supported. Since the while mapped
+ portion of the file must be present in memory, there are limitations
+ in the size of files that may be memory mapped (especially on MCUs
+ with no significant RAM resources).
+
+ c. All mapped files are read-only. You can write to the in-memory image,
+ but the file contents will not change.
+
+ d. There are no access privileges.
+
+ e. Since there are no processes in NuttX, all mmap() and munmap()
+ operations have immediate, global effects. Under Linux, for example,
+ munmap() would eliminate only the mapping with a process; the mappings
+ to the same file in other processes would not be effected.
+
+ f. Like true mapped file, the region will persist after closing the file
+ descriptor. However, at present, these ram copied file regions are
+ *not* automatically "unmapped" (i.e., freed) when a thread is terminated.
+ This is primarily because it is not possible to know how many users
+ of the mapped region there are and, therefore, when would be the
+ appropriate time to free the region (other than when munmap is called).
+
+ NOTE: Note, if the design limitation of a) were solved, then it would be
+ easy to solve exception d) as well.
diff --git a/nuttx/fs/mmap/fs_mmap.c b/nuttx/fs/mmap/fs_mmap.c
index 3a69e5167f..5764b16f1d 100644
--- a/nuttx/fs/mmap/fs_mmap.c
+++ b/nuttx/fs/mmap/fs_mmap.c
@@ -47,6 +47,7 @@
#include <debug.h>
#include "fs_internal.h"
+#include "fs_rammap.h"
/****************************************************************************
* Global Functions
@@ -135,16 +136,15 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
(flags & (MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_DENYWRITE)) != 0)
{
fdbg("Unsupported options, prot=%x flags=%04x\n", prot, flags);
- ret = ENOSYS;
- goto errout_with_ret;
+ errno = ENOSYS;
+ return MAP_FAILED;
}
- if (length == 0 ||
- (flags & MAP_SHARED) == 0)
+ if (length == 0 || (flags & MAP_SHARED) == 0)
{
fdbg("Invalid options, lengt=%d flags=%04x\n", length, flags);
- ret = EINVAL;
- goto errout_with_ret;
+ errno = EINVAL;
+ return MAP_FAILED;
}
#endif
@@ -161,24 +161,14 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
if (ret < 0)
{
#ifdef CONFIG_FS_RAMMAP
- ret = rammap(fd, length, offset, &addr);
- if (ret < 0)
+ return rammap(fd, length, offset);
+#else
+ fdbg("ioctl(FIOC_MMAP) failed: %d\n", errno);
+ return MAP_FAILED;
#endif
- {
- fdbg("ioctl(FIOC_MMAP) failed: %d\n", errno);
- goto errout;
- }
}
/* Return the offset address */
return (void*)(((uint8_t*)addr) + offset);
-
-#ifdef CONFIG_DEBUG
-errout_with_ret:
- errno = ret;
-#endif
-
-errout:
- return MAP_FAILED;
}
diff --git a/nuttx/fs/mmap/fs_munmap.c b/nuttx/fs/mmap/fs_munmap.c
index df0f471ac8..a4b9dc6091 100644
--- a/nuttx/fs/mmap/fs_munmap.c
+++ b/nuttx/fs/mmap/fs_munmap.c
@@ -44,9 +44,13 @@
#include <stdint.h>
#include <errno.h>
+#include <assert.h>
#include <debug.h>
+#include <nuttx/kmalloc.h>
+
#include "fs_internal.h"
+#include "fs_rammap.h"
#ifdef CONFIG_FS_RAMMAP
@@ -60,8 +64,8 @@
* Description:
*
* munmap() system call deletes mappings for the specified address range.
- * The region is also automatically unmapped when the process is terminated.
- * On the other hand, closing the file descriptor does not unmap the region.
+ * 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
@@ -96,8 +100,7 @@
* 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 umapped. Ignored. The entire underlying
- * media is always freed.
+ * length The length region to be umapped.
*
* Returned Value:
* On success, munmap() returns 0, on failure -1, and errno is set
@@ -110,13 +113,14 @@ int munmap(FAR void *start, size_t length)
FAR struct fs_rammap_s *prev;
FAR struct fs_rammap_s *curr;
FAR void *newaddr;
+ unsigned int offset;
int ret;
int err;
/* Find a region containing this start and length in the list of regions */
-#warning "Missing semaphore initialization"
- ret = sem_wait(g_rammaps.exclsem);
+ rammap_initialize();
+ ret = sem_wait(&g_rammaps.exclsem);
if (ret < 0)
{
return ERROR;
@@ -124,7 +128,7 @@ int munmap(FAR void *start, size_t length)
/* Seach the list of regions */
- for (prev = NULL, curr = g_rammaps.head; prev = curr, curr = curr->flink)
+ for (prev = NULL, curr = g_rammaps.head; curr; prev = curr, curr = curr->flink)
{
/* Does this region include any part of the specified range? */
@@ -144,32 +148,63 @@ int munmap(FAR void *start, size_t length)
goto errout_with_semaphore;
}
- /* There is not yet any support for freeing memory at the beginning of the
- * region or for increasing the size of the mapped region.
+ /* Get the offset from the beginning of the region and the actual number
+ * of bytes to "unmap". All mappings must extend to the end of the region.
+ * There is no support for free a block of memory but leaving a block of
+ * memory at the end. This is a consequence of using realloc() to
+ * simulate the unmapping.
*/
- if (start != curr->addr || length > curr->length)
+ offset = start - curr->addr;
+ if (offset + length < curr->length)
{
- fdbg("Unmapping at offset/Extending not supported\n");
+ fdbg("Cannot umap without unmapping to the end\n");
err = ENOSYS;
goto errout_with_semaphore;
}
- /* Otherwise, we can simply realloc the region. Since we are reducing
- * the size of the region, this should not change the start addres.
+ /* Okay.. the region is beging umapped to the end. Make sure the length
+ * indicates that.
+ */
+
+ length = curr->length - offset;
+
+ /* Are we unmapping the entire region (offset == 0)? */
+
+ if (length >= curr->length)
+ {
+ /* Yes.. remove the mapping from the list */
+
+ if (prev)
+ {
+ prev->flink = curr->flink;
+ }
+ else
+ {
+ g_rammaps.head = curr->flink;
+ }
+
+ /* Then free the region */
+
+ kfree(curr);
+ }
+
+ /* No.. We have been asked to "unmap' only a portion of the memory
+ * (offset > 0).
*/
- if (length < curr->length)
+ else
{
- newaddr = realloc(curr->addr, length);
- DEBUGASSERT(newaddr == curr->addr);
+ newaddr = krealloc(curr->addr, sizeof(struct fs_rammap_s) + length);
+ DEBUGASSERT(newaddr == (FAR void*)(curr->addr));
+ curr->length = length;
}
- sem_post(g_rammaps.exclsem);
+ sem_post(&g_rammaps.exclsem);
return OK;
errout_with_semaphore:
- sem_post(g_rammaps.exclsem);
+ sem_post(&g_rammaps.exclsem);
errno = err;
return ERROR;
}
diff --git a/nuttx/fs/mmap/fs_rammap.c b/nuttx/fs/mmap/fs_rammap.c
index 4136882af2..0eaf313b59 100644
--- a/nuttx/fs/mmap/fs_rammap.c
+++ b/nuttx/fs/mmap/fs_rammap.c
@@ -40,20 +40,56 @@
#include <nuttx/config.h>
#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <debug.h>
+#include <nuttx/kmalloc.h>
+
#include "fs_internal.h"
+#include "fs_rammap.h"
#ifdef CONFIG_FS_RAMMAP
/****************************************************************************
+ * Global Data
+ ****************************************************************************/
+
+/* This is the list of all mapped files */
+
+struct fs_allmaps_s g_rammaps;
+
+/****************************************************************************
* Global Functions
****************************************************************************/
/****************************************************************************
+ * Name: rammap_initialize
+ *
+ * Description:
+ * Verified that this capability has been initialized.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void rammap_initialize(void)
+{
+ if (!g_rammaps.initialized)
+ {
+ sem_init(&g_rammaps.exclsem, 0, 1);
+ g_rammaps.initialized = true;
+ }
+}
+
+/****************************************************************************
* Name: rammmap
*
* Description:
@@ -78,9 +114,9 @@
*
****************************************************************************/
-int rammap(int fd, size_t length, off_t offset, FAR void **addr)
+FAR void *rammap(int fd, size_t length, off_t offset)
{
- FAR struct fs_rammap_s *rammap;
+ FAR struct fs_rammap_s *map;
FAR uint8_t *alloc;
FAR uint8_t *rdbuffer;
ssize_t nread;
@@ -113,11 +149,11 @@ int rammap(int fd, size_t length, off_t offset, FAR void **addr)
/* Initialize the region */
- rammap = (FAR struct fs_rammap_s *)alloc;
- memset(rammap, 0, sizeof(struct fs_rammap_s));
- rammap->addr = alloc + sizeof(struct fs_rammap_s);
- rammap->length = length;
- rammap->offset = offset;
+ map = (FAR struct fs_rammap_s *)alloc;
+ memset(map, 0, sizeof(struct fs_rammap_s));
+ map->addr = alloc + sizeof(struct fs_rammap_s);
+ map->length = length;
+ map->offset = offset;
/* Seek to the specified file offset */
@@ -135,7 +171,7 @@ int rammap(int fd, size_t length, off_t offset, FAR void **addr)
/* Read the file data into the memory region */
- rdbuffer = rammap->addr;
+ rdbuffer = map->addr;
while (length > 0)
{
nread = read(fd, rdbuffer, length);
@@ -175,18 +211,18 @@ int rammap(int fd, size_t length, off_t offset, FAR void **addr)
/* Add the buffer to the list of regions */
-#warning "Missing semaphore initialization"
- ret = sem_wait(g_rammaps.exclsem);
+ rammap_initialize();
+ ret = sem_wait(&g_rammaps.exclsem);
if (ret < 0)
{
goto errout_with_errno;
}
- rammap->flink = g_rammaps.head;
- g_rammaps.head = rammap;
+ map->flink = g_rammaps.head;
+ g_rammaps.head = map;
- sem_post(g_rammaps.exclsem);
- return rammap->addr;
+ sem_post(&g_rammaps.exclsem);
+ return map->addr;
errout_with_region:
kfree(alloc);
@@ -195,8 +231,8 @@ errout:
return MAP_FAILED;
errout_with_errno:
- kfree(alloc)
- returm MAP_FAILED;
+ kfree(alloc);
+ return MAP_FAILED;
}
#endif /* CONFIG_FS_RAMMAP */
diff --git a/nuttx/fs/mmap/fs_rammap.h b/nuttx/fs/mmap/fs_rammap.h
index db19f215ce..9076d73432 100644
--- a/nuttx/fs/mmap/fs_rammap.h
+++ b/nuttx/fs/mmap/fs_rammap.h
@@ -64,25 +64,31 @@
* blocks of a file.
*
* This copied file has many of the properties of a standard memory mapped
- * file except for all of the file must be present in memory. This limits
- * the size of files that may be memory mapped (especially on MCUs with
- * no significant RAM resources).
+ * file except:
+ *
+ * - All of the file must be present in memory. This limits the size of
+ * files that may be memory mapped (especially on MCUs with no significant
+ * RAM resources).
+ * - All mapped files are read-only. You can write to the in-memory image,
+ * but the file contents will not change.
+ * - There are not access privileges.
*/
struct fs_rammap_s
{
- struct fs_rammap_s *flink; /* Implements a singly linked list */
- FAR void *addr; /* Start of allocated memory */
- size_t length; /* Length of region */
- off_t offset; /* File offset */
+ struct fs_rammap_s *flink; /* Implements a singly linked list */
+ FAR void *addr; /* Start of allocated memory */
+ size_t length; /* Length of region */
+ off_t offset; /* File offset */
};
/* This structure defines all "mapped" files */
struct fs_allmaps_s
{
- sem_t exclsem; /* Provides exclusive access the list */
- struct fs_rammap_s *maps; /* List of mapped files */
+ bool initialized; /* True: This structure has been initialized */
+ sem_t exclsem; /* Provides exclusive access the list */
+ struct fs_rammap_s *head; /* List of mapped files */
};
/****************************************************************************
@@ -98,6 +104,22 @@ extern struct fs_allmaps_s g_rammaps;
****************************************************************************/
/****************************************************************************
+ * Name: rammap_initialize
+ *
+ * Description:
+ * Verified that this capability has been initialized.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+extern void rammap_initialize(void);
+
+/****************************************************************************
* Name: rammmap
*
* Description:
@@ -122,7 +144,7 @@ extern struct fs_allmaps_s g_rammaps;
*
****************************************************************************/
-extern int rammap(int fd, size_t length, off_t offset, FAR void **addr);
+extern FAR void *rammap(int fd, size_t length, off_t offset);
#endif /* CONFIG_FS_RAMMAP */
#endif /* __FS_MMAP_RAMMAP_H */
diff --git a/nuttx/include/sys/mman.h b/nuttx/include/sys/mman.h
index 81bed9ca25..6d220bef10 100644
--- a/nuttx/include/sys/mman.h
+++ b/nuttx/include/sys/mman.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/sys/mman.h
*
- * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2008, 2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -98,7 +98,12 @@ extern "C" {
EXTERN FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
int fd, off_t offset);
-#define munmap(start, length)
+
+#ifdef CONFIG_FS_RAMMAP
+EXTERN int munmap(FAR void *start, size_t length);
+#else
+# define munmap(start, length)
+#endif
#undef EXTERN
#if defined(__cplusplus)