apps/examples/module: Add support for CROMFS and for stripping symbols from ELF module binaries.

This commit is contained in:
Gregory Nutt 2018-08-05 14:10:44 -06:00
parent 6210fcae8b
commit b980e943c7
4 changed files with 138 additions and 32 deletions

View File

@ -16,7 +16,7 @@ if EXAMPLES_MODULE
config EXAMPLES_MODULE_BUILTINFS
bool "Built-in File System"
default y
depends on FS_ROMFS && BUILD_FLAT
depends on (FS_ROMFS || FS_CROMFS) && BUILD_FLAT
---help---
This example supports a very, non-standard but also very convenient
way of testing with example using CONFIG_EXAMPLES_MODULE_BUILTINFS.
@ -29,16 +29,39 @@ config EXAMPLES_MODULE_BUILTINFS
If this option is not selected, then the modules will be left in
the fsroot/ directory. You can then copy them to, say an SD card,
for testing on the target.
for testing on the target. That file system will need to be mounted
such that CONFIG_EXAMPLES_MODULE_BINDIR refers to the directory
containing the module binaries.
NOTE: This option can only be used in the FLAT build mode because
it makes an illegal OS call to ramdisk_register().
if EXAMPLES_MODULE_BUILTINFS
choice
prompt "Built-in file system type"
default EXAMPLES_MODULE_ROMFS if FS_ROMFS
default EXAMPLES_MODULE_CROMFS if !FS_ROMFS && FS_CROMFS
depends on EXAMPLES_MODULE_BUILTINFS
config EXAMPLES_MODULE_ROMFS
bool "ROMFS"
depends on FS_ROMFS && BUILD_FLAT
---help---
Automatically generates and mounts an internal ROMFS file
system
config EXAMPLES_MODULE_CROMFS
bool "CROMFS"
depends on FS_CROMFS && BUILD_FLAT
---help---
Automatically generates and mounts an internal CROMFS file
system
endchoice # Built-in file system type
config EXAMPLES_MODULE_DEVMINOR
int "ROMFS Minor Device Number"
default 0
depends on EXAMPLES_MODULE_ROMFS
---help---
The minor device number of the ROMFS block. For example, the N in /dev/ramN.
Used for registering the RAM block driver that will hold the ROMFS file system
@ -47,23 +70,30 @@ config EXAMPLES_MODULE_DEVMINOR
config EXAMPLES_MODULE_DEVPATH
string "ROMFS Device Path"
default "/dev/ram0"
depends on EXAMPLES_MODULE_ROMFS
---help---
The path to the ROMFS block driver device. This must match EXAMPLES_MODULE_DEVMINOR.
Used for registering the RAM block driver that will hold the ROMFS file system
containing the MODULE executables to be tested. Default: "/dev/ram0"
endif # EXAMPLES_MODULE_BUILTINFS
if !EXAMPLES_MODULE_BUILTINFS
config EXAMPLES_MODULE_BINDIR
string "Path to Test Modules"
default "/mnt/sdcard"
depends on !EXAMPLES_MODULE_BUILTINFS
---help---
The path to the directory on the mounted volume where the test
modules can found at runtime.
endif # !EXAMPLES_MODULE_BUILTINFS
config EXAMPLES_MODULE_NOSTRIP
bool "Do not strip debug symbols"
default n
depends on DEBUG_SYMBOLS
---help---
By default, if debug symbols are enabled (via CONFIG_DEBUG_SYMBOLS), then the
ELF executables will also retain debug symbols in the resulting ELF binaries.
Select this option if you do not want that behavior, this option will permit
debug symbols in the base code but will strip debug symbols out of the ELF
binaries for a smaller ROM file system image.
config EXAMPLES_MODULE_LIBC
bool "Link with LIBC"
@ -73,8 +103,8 @@ config EXAMPLES_MODULE_LIBC
Link with the C library (and also math library if it was built).
By default, all undefined symbols must be provided via a symbol
table. But if this option is selected, then each MODULE test program
will link with the SYSCALL library and will interface with the OS
system calls. You probably will NOT want this option, however,
will link with the C library and will not require symbol table
entries. You probably will NOT want this option, however,
because it will substantially increase the size of code. For
example, a separate copy of printf() would be linked with every
program greatly increasing the total code size. This option is

View File

@ -1,5 +1,6 @@
/fsroot
/romfs.h
/cromfs.h
/romfs.img
/mod_symtab.c

View File

@ -1,7 +1,7 @@
############################################################################
# apps/examples/module/drivers/Makefile
#
# Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
# Copyright (C) 2015, 2017-2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -39,20 +39,30 @@ include $(APPDIR)/Make.defs
ALL_SUBDIRS = chardev
BUILD_SUBDIRS = chardev
FSIMG_SUBDIR = fsroot
MODULE_DIR = $(APPDIR)/examples/module
DRIVER_DIR = $(MODULE_DIR)/drivers
FSROOT_DIR = $(DRIVER_DIR)/fsroot
ROMFS_IMG = $(DRIVER_DIR)/romfs.img
ROMFS_HDR = $(DRIVER_DIR)/romfs.h
SYMTAB_SRC = $(DRIVER_DIR)/mod_symtab.c
ifeq ($(CONFIG_EXAMPLES_MODULE_ROMFS),y)
ROMFS_IMG = $(DRIVER_DIR)/romfs.img
FSIMG_HDR = $(DRIVER_DIR)/romfs.h
else ifeq ($(CONFIG_EXAMPLES_MODULE_CROMFS),y)
NXTOOLDIR = $(TOPDIR)/tools
GENCROMFSSRC = gencromfs.c
GENCROMFSEXE = gencromfs$(EXEEXT)
FSIMG_HDR = $(DRIVER_DIR)/cromfs.h
endif
define DIR_template
$(1)_$(2):
$(Q) $(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" FSROOT_DIR="$(FSROOT_DIR)" CROSSDEV=$(CROSSDEV)
endef
all: $(ROMFS_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC)
all: $(FSIMG_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC)
.PHONY: all build clean install populate
.PRECIOUS: ../../../libapps$(LIBEXT)
@ -67,6 +77,11 @@ build: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_build)
# Install each program in the fsroot directory
install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install)
ifneq ($(STRIP),)
ifneq ($(CONFIG_EXAMPLES_MODULE_NOSTRIP),y)
$(Q) $(STRIP) $(wildcard $(FSIMG_SUBDIR)$(DELIM)*)
endif
endif
# Create the fsroot directory
@ -77,6 +92,8 @@ $(FSROOT_DIR):
populate: $(FSROOT_DIR) build install
ifeq ($(CONFIG_EXAMPLES_MODULE_BUILTINFS),y)
ifeq ($(CONFIG_EXAMPLES_MODULE_ROMFS),y)
# Create the romfs.img file from the populated fsroot directory
$(ROMFS_IMG): populate
@ -86,18 +103,40 @@ endif
# Create the romfs.h header file from the romfs.img file
$(ROMFS_HDR) : $(ROMFS_IMG)
$(FSIMG_HDR) : $(ROMFS_IMG)
ifeq ($(CONFIG_EXAMPLES_MODULE_BUILTINFS),y)
$(Q) (cd $(DRIVER_DIR); xxd -i romfs.img | sed -e "s/^unsigned/static const unsigned/g" >$@)
endif
else ifeq ($(CONFIG_EXAMPLES_MODULE_CROMFS),y)
# Make sure that the NuttX gencromfs tool has been built
$(NXTOOLDIR)/$(GENCROMFSEXE): $(NXTOOLDIR)/$(GENCROMFSSRC)
$(Q) $(MAKE) -C $(NXTOOLDIR) -f Makefile.host $(GENCROMFSEXE)
# Create the cromfs.h header file from the populated cromfs directory
$(FSIMG_HDR) : populate $(NXTOOLDIR)/$(GENCROMFSEXE)
$(Q) $(NXTOOLDIR)/$(GENCROMFSEXE) $(FSIMG_DIR) $(FSIMG_HDR)
endif
# Create the exported symbol table
$(SYMTAB_SRC): build
$(Q) $(DRIVER_DIR)/mksymtab.sh $(FSROOT_DIR) >$@
else
# Create the exported symbol table
$(SYMTAB_SRC): build populate
$(Q) $(DRIVER_DIR)/mksymtab.sh $(FSROOT_DIR) >$@
endif
# Clean each subdirectory
clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean)
$(Q) rm -f $(ROMFS_HDR) $(DIRLIST_HDR) $(ROMFS_IMG) $(SYMTAB_SRC)
$(Q) rm -f $(FSIMG_HDR) $(DIRLIST_HDR) $(ROMFS_IMG) $(SYMTAB_SRC)
$(Q) rm -rf $(FSROOT_DIR)

View File

@ -1,7 +1,7 @@
/****************************************************************************
* examples/module/module_main.c
*
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2015, 2017-2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -57,9 +57,11 @@
#include <nuttx/module.h>
#include <nuttx/binfmt/symtab.h>
#ifdef CONFIG_EXAMPLES_MODULE_BUILTINFS
#if defined(CONFIG_EXAMPLES_MODULE_ROMFS)
# include <nuttx/drivers/ramdisk.h>
# include "drivers/romfs.h"
#elif defined(CONFIG_EXAMPLES_MODULE_CROMFS)
# include "drivers/cromfs.h"
#endif
/****************************************************************************
@ -79,8 +81,8 @@
#endif
#ifdef CONFIG_EXAMPLES_MODULE_BUILTINFS
# ifndef CONFIG_FS_ROMFS
# error "You must select CONFIG_FS_ROMFS in your configuration file"
# if !defined(CONFIG_FS_ROMFS) || !defined(CONFIG_FS_CROMFS)
# error "You must select CONFIG_FS_ROMFS or CONFIG_FS_CROMFS in your configuration file"
# endif
# ifdef CONFIG_DISABLE_MOUNTPOINT
@ -89,9 +91,10 @@
/* Describe the ROMFS file system */
# if defined(CONFIG_EXAMPLES_ELF_CROMFS)
# define SECTORSIZE 64
# define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
# define BINDIR "/mnt/romfs"
# define MOUNTPT "/mnt/romfs"
# ifndef CONFIG_EXAMPLES_MODULE_DEVMINOR
# define CONFIG_EXAMPLES_MODULE_DEVMINOR 0
@ -100,6 +103,14 @@
# ifndef CONFIG_EXAMPLES_MODULE_DEVPATH
# define CONFIG_EXAMPLES_MODULE_DEVPATH "/dev/ram0"
# endif
# elif defined(CONFIG_EXAMPLES_ELF_CROMFS)
/* Describe the CROMFS file system */
# define MOUNTPT "/mnt/cromfs"
# endif
# define BINDIR MOUNTPT
#else
# define BINDIR CONFIG_EXAMPLES_MODULE_BINDIR
#endif /* CONFIG_EXAMPLES_MODULE_BUILTINFS */
@ -150,11 +161,21 @@ int module_main(int argc, char *argv[])
}
#ifdef CONFIG_EXAMPLES_MODULE_BUILTINFS
#if defined(CONFIG_EXAMPLES_ELF_ROMFS)
/* Create a ROM disk for the ROMFS filesystem */
printf("main: Registering romdisk at /dev/ram%d\n",
CONFIG_EXAMPLES_MODULE_DEVMINOR);
#if defined(CONFIG_BUILD_FLAT)
/* This example violates the portable POSIX interface by calling the OS
* internal function romdisk_register() (aka ramdisk_register()). We can
* squeak by in with this violation in the FLAT build mode, but not in
* other build modes. In other build modes, the following logic must be
* performed in the OS board initialization logic (where it really belongs
* anyway).
*/
ret = romdisk_register(CONFIG_EXAMPLES_MODULE_DEVMINOR, (FAR uint8_t *)romfs_img,
NSECTORS(romfs_img_len), SECTORSIZE);
if (ret < 0)
@ -169,19 +190,34 @@ int module_main(int argc, char *argv[])
printf("main: ROM disk already registered\n");
}
#endif
/* Mount the file system */
printf("main: Mounting ROMFS filesystem at target=%s with source=%s\n",
BINDIR, CONFIG_EXAMPLES_MODULE_DEVPATH);
MOUNTPT, CONFIG_EXAMPLES_MODULE_DEVPATH);
ret = mount(CONFIG_EXAMPLES_MODULE_DEVPATH, BINDIR, "romfs", MS_RDONLY, NULL);
ret = mount(CONFIG_EXAMPLES_MODULE_DEVPATH, MOUNTPT, "romfs",
MS_RDONLY, NULL);
if (ret < 0)
{
fprintf(stderr, "ERROR: mount(%s,%s,romfs) failed: %s\n",
CONFIG_EXAMPLES_MODULE_DEVPATH, BINDIR, errno);
CONFIG_EXAMPLES_MODULE_DEVPATH, MOUNTPT, errno);
exit(EXIT_FAILURE);
}
#elif defined(CONFIG_EXAMPLES_ELF_CROMFS)
/* Mount the CROMFS file system */
printf("Mounting CROMFS filesystem at target=%s\n", MOUNTPT);
ret = mount(NULL, MOUNTPT, "cromfs", MS_RDONLY, NULL);
if (ret < 0)
{
errmsg("ERROR: mount(%s, cromfs) failed: %d\n", MOUNTPT, errno);
}
#endif /* CONFIG_EXAMPLES_ELF_ROMFS */
#endif /* CONFIG_EXAMPLES_MODULE_BUILTINFS */
/* Install the character driver */