| #!/usr/bin/env bash |
| ############################################################################ |
| # tools/mkromfsimg.sh |
| # |
| # 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. |
| # |
| ############################################################################ |
| |
| # Environmental stuff |
| |
| wd=`pwd` |
| workingdir=$wd/img |
| rcsysinitfile=rc.sysinit |
| rcsysinittemplate=$rcsysinitfile.template |
| rcsfile=rcS |
| rcstemplate=$rcsfile.template |
| romfsimg=romfs.img |
| headerfile=etc_romfs.c |
| |
| # Get the input parameters |
| |
| nofat=$1 |
| usefat=true |
| topdir=$2 |
| rcsysinit_fname=$3 |
| rcs_fname=$4 |
| usage="USAGE: $0 [-nofat] <topdir> [rcsysinitfile] [<rcsfile>]" |
| |
| # Verify if we have the optional "-nofat" |
| |
| if [ "$nofat" == "-nofat" ]; then |
| echo "We will not mount a FAT/RAMDISK!" |
| usefat=false |
| else |
| topdir=$1 |
| rcsysinit_fname=$2 |
| rcs_fname=$3 |
| fi |
| |
| if [ -z "$topdir" -o ! -d "$topdir" ]; then |
| echo "The full path to the NuttX base directory must be provided on the command line" |
| echo $usage |
| exit 1 |
| fi |
| |
| # Verify if we have the optional "rcsysinit_fname" and "rcs_fname" |
| |
| if [ ! -z "$rcsysinit_fname" ]; then |
| rcsysinittemplate=$rcsysinit_fname |
| echo "Target template is $rcsysinittemplate" |
| fi |
| |
| if [ ! -z "$rcs_fname" ]; then |
| rcstemplate=$rcs_fname |
| echo "Target template is $rcstemplate" |
| fi |
| |
| # Extract all values from the .config in the $topdir that contains all of the NuttX |
| # configuration settings. The .config file was intended to be include-able by makefiles |
| # and source-able by scripts. Unfortunately,there are too many syntactic difference |
| # to make that practical |
| |
| if [ ! -r $topdir/.config ]; then |
| echo "No readable file at $topdir/.config" |
| echo "Has NuttX been configured?" |
| exit 1 |
| fi |
| |
| romfsetc=`grep CONFIG_ETC_ROMFS= $topdir/.config | cut -d'=' -f2` |
| disablempt=`grep CONFIG_DISABLE_MOUNTPOINT= $topdir/.config | cut -d'=' -f2` |
| disablescript=`grep CONFIG_NSH_DISABLESCRIPT= $topdir/.config | cut -d'=' -f2` |
| devconsole=`grep CONFIG_DEV_CONSOLE= $topdir/.config | cut -d'=' -f2` |
| romfs=`grep CONFIG_FS_ROMFS= $topdir/.config | cut -d'=' -f2` |
| romfsmpt=`grep CONFIG_ETC_ROMFSMOUNTPT= $topdir/.config | cut -d'=' -f2` |
| initscript=`grep CONFIG_NSH_INITSCRIPT= $topdir/.config | cut -d'=' -f2` |
| sysinitscript=`grep CONFIG_NSH_SYSINITSCRIPT= $topdir/.config | cut -d'=' -f2` |
| romfsdevno=`grep CONFIG_ETC_ROMFSDEVNO= $topdir/.config | cut -d'=' -f2` |
| romfssectsize=`grep CONFIG_ETC_ROMFSSECTSIZE= $topdir/.config | cut -d'=' -f2` |
| |
| # If we disabled FAT FS requirement, we don't need to check it |
| |
| if [ "$usefat" = true ]; then |
| fatfs=`grep CONFIG_FS_FAT= $topdir/.config | cut -d'=' -f2` |
| fatdevno=`grep CONFIG_ETC_FATDEVNO= $topdir/.config | cut -d'=' -f2` |
| fatsectsize=`grep CONFIG_ETC_FATSECTSIZE= $topdir/.config | cut -d'=' -f2` |
| fatnsectors=`grep CONFIG_ETC_FATNSECTORS= $topdir/.config | cut -d'=' -f2` |
| fatmpt=`grep CONFIG_ETC_FATMOUNTPT= $topdir/.config | cut -d'=' -f2` |
| fi |
| |
| # The following settings are required for general ROMFS support |
| # |
| # Mountpoint support must be enabled |
| |
| if [ "X$disablempt" = "Xy" ]; then |
| echo "Mountpoint support is required for this feature" |
| echo "Set CONFIG_DISABLE_MOUNTPOINT=n to continue" |
| exit 1 |
| fi |
| |
| # Scripting support must be enabled |
| |
| if [ "X$disablescript" = "Xy" ]; then |
| echo "NSH scripting support is required for this feature" |
| echo "Set CONFIG_NSH_DISABLESCRIPT=n to continue" |
| exit 1 |
| fi |
| |
| # ROMFS support is required, of course |
| |
| if [ "X$romfs" != "Xy" ]; then |
| echo "ROMFS support is disabled in the NuttX configuration" |
| echo "Set CONFIG_FS_ROMFS=y to continue" |
| exit 0 |
| fi |
| |
| # If it is the default rcS.template, then it also requires FAT FS support |
| |
| if [ "$usefat" = true -a "X$fatfs" != "Xy" ]; then |
| echo "FAT FS support is disabled in the NuttX configuration" |
| echo "Set CONFIG_FS_FAT=y to continue" |
| exit 0 |
| fi |
| |
| # Verify that genromfs has been installed |
| |
| genromfs -h 1>/dev/null 2>&1 || { \ |
| echo "Host executable genromfs not available in PATH"; \ |
| echo "You may need to download in from http://romfs.sourceforge.net/"; \ |
| exit 1; \ |
| } |
| |
| # Supply defaults for all un-defined ROMFS settings |
| |
| if [ -z "$romfsmpt" ]; then |
| romfsmpt=\"/etc\" |
| fi |
| if [ -z "$initscript" ]; then |
| initscript=\"init.d/rcS\" |
| fi |
| if [ -z "$sysinitscript" ]; then |
| sysinitscript=\"init.d/rc.sysinit\" |
| fi |
| if [ -z "$romfsdevno" ]; then |
| romfsdevno=0 |
| fi |
| if [ -z "$romfssectsize" ]; then |
| romfssectsize=64 |
| fi |
| |
| # If FAT FS is a requirement |
| |
| if [ "$usefat" = true ]; then |
| |
| # Supply defaults for all un-defined FAT FS settings |
| |
| if [ -z "$fatdevno" ]; then |
| fatdevno=1 |
| fi |
| if [ -z "$fatsectsize" ]; then |
| fatsectsize=512 |
| fi |
| if [ -z "$fatnsectors" ]; then |
| fatnsectors=1024 |
| fi |
| if [ -z "$fatmpt" ]; then |
| fatmpt=\"/tmp\" |
| fi |
| fi |
| |
| # Verify the mountpoint. Verify that it is an absolute path but not /, /dev, |
| # /., /./*, /.., or /../* |
| |
| if [ ${romfsmpt:0:1} != "\"" ]; then |
| echo "CONFIG_ETC_ROMFSMOUNTPT must be a string" |
| echo "Change it so that it is enclosed in quotes." |
| exit 1 |
| fi |
| |
| uromfsmpt=`echo $romfsmpt | sed -e "s/\"//g"` |
| |
| if [ ${uromfsmpt:0:1} != "/" ]; then |
| echo "CONFIG_ETC_ROMFSMOUNTPT must be an absolute path in the target FS" |
| echo "Change it so that it begins with the character '/'. Eg. /etc" |
| exit 1 |
| fi |
| |
| tmpdir=$uromfsmpt |
| while [ ${tmpdir:0:1} == "/" ]; do |
| tmpdir=${tmpdir:1} |
| done |
| |
| if [ -z "$tmpdir" -o "X$tmpdir" = "Xdev" -o "X$tmpdir" = "." -o \ |
| ${tmpdir:0:2} = "./" -o "X$tmpdir" = ".." -o ${tmpdir:0:3} = "../" ]; then |
| echo "Invalid CONFIG_ETC_ROMFSMOUNTPT selection." |
| exit 1 |
| fi |
| |
| # Verify that the path to the init file is a relative path and not ., ./*, .., or ../* |
| |
| if [ ${initscript:0:1} != "\"" ]; then |
| echo "CONFIG_NSH_INITSCRIPT must be a string" |
| echo "Change it so that it is enclosed in quotes." |
| exit 1 |
| fi |
| |
| uinitscript=`echo $initscript | sed -e "s/\"//g"` |
| |
| if [ ${uinitscript:0:1} == "/" ]; then |
| echo "CONFIG_NSH_INITSCRIPT must be an relative path in under $romfsmpt" |
| echo "Change it so that it begins with the character '/'. Eg. init.d/rcS. " |
| exit 1 |
| fi |
| |
| if [ "X$uinitscript" = "." -o ${uinitscript:0:2} = "./" -o \ |
| "X$uinitscript" = ".." -o ${uinitscript:0:3} = "../" ]; then |
| echo "Invalid CONFIG_NSH_INITSCRIPT selection. Must not begin with . or .." |
| exit 1 |
| fi |
| |
| if [ ${sysinitscript:0:1} != "\"" ]; then |
| echo "CONFIG_NSH_SYSINITSCRIPT must be a string" |
| echo "Change it so that it is enclosed in quotes." |
| exit 1 |
| fi |
| |
| usysinitscript=`echo $sysinitscript | sed -e "s/\"//g"` |
| |
| if [ ${usysinitscript:0:1} == "/" ]; then |
| echo "CONFIG_NSH_SYSINITSCRIPT must be an relative path in under $romfsmpt" |
| echo "Change it so that it begins with the character '/'. Eg. init.d/rc.sysinit. " |
| exit 1 |
| fi |
| |
| if [ "X$usysinitscript" = "." -o ${usysinitscript:0:2} = "./" -o \ |
| "X$usysinitscript" = ".." -o ${usysinitscript:0:3} = "../" ]; then |
| echo "Invalid CONFIG_NSH_SYSINITSCRIPT selection. Must not begin with . or .." |
| exit 1 |
| fi |
| |
| # Create a working directory |
| |
| rm -rf $workingdir || { echo "Failed to remove the old $workingdir"; exit 1; } |
| mkdir -p $workingdir || { echo "Failed to created the new $workingdir"; exit 1; } |
| |
| # Create the rc.sysinit file from the rc.sysinit.template |
| |
| if [ ! -r $rcsysinittemplate ]; then |
| echo "$rcsysinittemplate does not exist" |
| rmdir $workingdir |
| exit 1 |
| fi |
| |
| # If we are using FAT FS with RAMDISK we need to setup it |
| |
| if [ "$usefat" = true ]; then |
| cat $rcsysinittemplate | \ |
| sed -e "s,XXXMKRDMINORXXX,$fatdevno,g" | \ |
| sed -e "s,XXMKRDSECTORSIZEXXX,$fatsectsize,g" | \ |
| sed -e "s,XXMKRDBLOCKSXXX,$fatnsectors,g" | \ |
| sed -e "s,XXXRDMOUNTPOINTXXX,$fatmpt,g" >$rcsysinitfile |
| else |
| cp $rcsysinittemplate $rcsysinitfile |
| fi |
| |
| # Create the rcS file from the rcS.template |
| |
| if [ ! -r $rcstemplate ]; then |
| echo "$rcstemplate does not exist" |
| rmdir $workingdir |
| exit 1 |
| fi |
| |
| cp $rcstemplate $rcsfile |
| |
| # And install it at the specified relative location |
| |
| # Fix for BSD install without -D option |
| mkdir -p $workingdir/$uinitscript |
| rmdir $workingdir/$uinitscript |
| |
| install -m 0755 $rcsysinitfile $workingdir/$usysinitscript || \ |
| { echo "Failed to install $rcsysinitfile at $workingdir/$usysinitscript"; rm -f $rcsysinitfile; exit 1; } |
| rm -f $rcsysinitfile |
| |
| install -m 0755 $rcsfile $workingdir/$uinitscript || \ |
| { echo "Failed to install $rcsfile at $workingdir/$uinitscript"; rm -f $rcsfile; exit 1; } |
| rm -f $rcsfile |
| |
| # Now we are ready to make the ROMFS image |
| |
| genromfs -f $romfsimg -d $workingdir -V "NSHInitVol" || { echo "genromfs failed" ; exit 1 ; } |
| rm -rf $workingdir || { echo "Failed to remove the old $workingdir"; exit 1; } |
| |
| # And, finally, create the header file |
| |
| echo '#include <nuttx/compiler.h>' >${headerfile} |
| xxd -i ${romfsimg} | sed 's/^unsigned char/const unsigned char aligned_data(4)/g' >>${headerfile} || \ |
| { echo "ERROR: xxd of $< failed" ; rm -f $romfsimg; exit 1 ; } |
| rm -f $romfsimg |