From f5072951cc0ddc165fea568a2733a19b51ed1cee Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 8 Sep 2010 17:38:44 +0000 Subject: Implement SD-based paging for EA3131 git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2931 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/configs/README.txt | 5 ++ nuttx/configs/ea3131/README.txt | 35 +++++++++++- nuttx/configs/ea3131/locked/mklocked.sh | 1 + nuttx/configs/ea3131/src/up_fillpage.c | 97 ++++++++++++++++++++++++++++++++- 4 files changed, 135 insertions(+), 3 deletions(-) (limited to 'nuttx/configs') diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt index 6603c9848..d94fdf7af 100644 --- a/nuttx/configs/README.txt +++ b/nuttx/configs/README.txt @@ -401,6 +401,11 @@ defconfig -- This is a configuration file similar to the Linux page table entry to use for the vector mapping. CONFIG_PAGING_VECL2VADDR - This is the virtual address of the L2 page table entry to use for the vector mapping. + CONFIG_PAGING_BINPATH - If CONFIG_PAGING_BINPATH is defined, then it + is the full path to a file on a mounted file system that contains + a binary image of the NuttX executable. Pages will be filled by + reading from offsets into this file that correspond to virtual + fault addresses. The following can be used to disable categories of APIs supported by the OS. If the compiler supports weak functions, then it diff --git a/nuttx/configs/ea3131/README.txt b/nuttx/configs/ea3131/README.txt index 2e3c1b874..556c4cb25 100755 --- a/nuttx/configs/ea3131/README.txt +++ b/nuttx/configs/ea3131/README.txt @@ -416,8 +416,41 @@ On-Demand Paging The references and issues related to this are discussed in (2) and (3) above. + Alternative: + ------------ + + I have implemented an alternative within configs/ea3131/src/up_fillpage.c + which is probably only useful for testing. Here is the usage module + for this alternative + + 1. Place the nuttx.bin file on an SD card. + 2. Insert the SD card prior to booting + 3. In up_fillpage(), use the virtual miss address (minus the virtual + base address) as an offset into the nuttx.bin file, and read the + required page from that offset in the nuttx.bin file: + + off_t offset = (off_t)vpage - PG_LOCKED_VBASE; + off_t pos = lseek(fd, offset, SEEK_SET); + if (pos != (off_t)-1) + { + int ret = read(fd, vpage, PAGESIZE); + } + + In this way, the paging implementation can do on-demand paging + from an image file on the SD card. Problems/issues with this + approach probably make it only useful for testing: + + 1. You would still have to boot the locked section over serial or + using a bootloader -- it is not clear how the power up boot + would occur. For testing, the nuttx.bin file could be both + provided on the SD card and loaded over serial. + 2. If the SD card is not in place, the system will crash. + 3. This means that all of the file system logic and FAT file + system would have to reside in the locked text region. + ARM/EA3131-specific Configuration Options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + CONFIG_ARCH - Identifies the arch/ subdirectory. This should be set to: @@ -500,7 +533,7 @@ ARM/EA3131-specific Configuration Options CONFIG_LPC313X_MCI, CONFIG_LPC313X_SPI, CONFIG_LPC313X_UART - xernal memory available on the board (see also CONFIG_MM_REGIONS) + External memory available on the board (see also CONFIG_MM_REGIONS) CONFIG_LPC313X_EXTSRAM0 - Select if external SRAM0 is present CONFIG_LPC313X_EXTSRAM0HEAP - Select if external SRAM0 should be diff --git a/nuttx/configs/ea3131/locked/mklocked.sh b/nuttx/configs/ea3131/locked/mklocked.sh index 3696888b0..bf6d52614 100755 --- a/nuttx/configs/ea3131/locked/mklocked.sh +++ b/nuttx/configs/ea3131/locked/mklocked.sh @@ -86,6 +86,7 @@ function checkzero () { echo "n" fi } + ############################################################################ # Interrupt Handlers ############################################################################ diff --git a/nuttx/configs/ea3131/src/up_fillpage.c b/nuttx/configs/ea3131/src/up_fillpage.c index 8f11dd48a..55c378152 100755 --- a/nuttx/configs/ea3131/src/up_fillpage.c +++ b/nuttx/configs/ea3131/src/up_fillpage.c @@ -47,15 +47,38 @@ #include #ifdef CONFIG_PAGING +#ifdef CONFIG_PAGING_BINPATH +# include +# include +# include +# include +# include +#endif /**************************************************************************** * Definitions ****************************************************************************/ +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef CONFIG_PAGING_BINPATH +struct pg_source_s +{ + bool initialized; /* TRUE: we are initialized */ + int fd; /* File descriptor of the nuttx.bin file */ +}; +#endif + /**************************************************************************** * Private Data ****************************************************************************/ +#ifdef CONFIG_PAGING_BINPATH +static struct pg_source_s g_pgsrc; +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -117,20 +140,80 @@ ****************************************************************************/ #ifdef CONFIG_PAGING_BLOCKINGFILL + +/* Version 1: Supports blocking fill operations */ + int up_fillpage(FAR _TCB *tcb, FAR void *vpage) { +#ifdef CONFIG_PAGING_BINPATH + ssize_t nbytes; + off_t offset; + off_t pos; +#endif + pglldbg("TCB: %p vpage: %p far: %08x\n", tcb, vpage, tcb->xcp.far); + DEBUGASSERT(tcb->xcp.far >= PG_PAGED_VBASE && tcb->xcp.far < PG_PAGED_VEND); + + /* If BINPATH is defined, then it is the full path to a file on a mounted file + * system. In this caseinitialization will be deferred until the first + * time that up_fillpage() is called. Are we initialized? + */ + +#ifdef CONFIG_PAGING_BINPATH + + if (!g_pgsrc.initialized) + { + /* Open the selected path for read-only access */ + + g_pgsrc.fd = open(CONFIG_PAGING_BINPATH, O_RDONLY); + DEBUGASSERT(g_pgsrc.fd >= 0); + g_pgsrc.initialized = true; + } + + /* Create an offset into the binary image that corresponds to the + * virtual address. File offset 0 corresponds to PG_LOCKED_VBASE. + */ + + offset = (off_t)vpage - PG_LOCKED_VBASE; + + /* Seek to that position */ + + pos = lseek(g_pgsrc.fd, offset, SEEK_SET); + DEBUGASSERT(pos != (off_t)-1); + + /* And read the page data from that offset */ + + nbytes = read(g_pgsrc.fd, vpage, PAGESIZE); + DEBUGASSERT(nbytes == PAGESIZE); + return OK; + +#else /* CONFIG_PAGING_BINPATH */ + # warning "Not implemented" return -ENOSYS; + +#endif /* CONFIG_PAGING_BINPATH */ } + #else + +/* Version 2: Supports non-blocking, asynchronous fill operations */ + int up_fillpage(FAR _TCB *tcb, FAR void *vpage, up_pgcallback_t pg_callback) { pglldbg("TCB: %p vpage: %d far: %08x\n", tcb, vpage, tcb->xcp.far); -# warning "Not implemented" + DEBUGASSERT(tcb->xcp.far >= PG_PAGED_VBASE && tcb->xcp.far < PG_PAGED_VEND); + +#ifdef CONFIG_PAGING_BINPATH +# error "File system-based paging must always be implemented with blocking calls" +#else +# warning "Not implemented" +#endif + return -ENOSYS; } -#endif + +#endif /* CONFIG_PAGING_BLOCKINGFILL */ /************************************************************************************ * Name: lpc313x_pginitialize @@ -154,6 +237,16 @@ void weak_function lpc313x_pginitialize(void) * - Do whatever else is necessary to make up_fillpage() ready for the first time * that it is called. */ + +#ifdef CONFIG_PAGING_BINPATH + /* If BINPATH is defined, then it is the full path to a file on a mounted file + * system. However, in this case, initialization will involve some higher level + * file system operations. Since this function is called from a low level (before + * os_start() is even called), it may not be possible to perform file system + * operations yet. Therefore, initialization will be deferred until the first + * time that up_fillpage() is called. + */ +#endif } #endif /* CONFIG_PAGING */ -- cgit v1.2.3