Nokia N900 >> Maemo

u-boot-update-bootmenu.sh


程式如下:

#!/bin/sh -e
#
#    u-boot-update-bootmenu - Generate and update Bootmenu for U-Boot
#    Copyright (C) 2012  Pali Rohár <pali.rohar@gmail.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

BOOTMENU_EMMC_DIR="/home/user/MyDocs"
BOOTMENU_CFG_DIR="/etc/bootmenu.d"
BOOTMENU_BOOT_DIR="/boot"
BOOTMENU_OPTBOOT_DIR="/opt/boot"
BOOTMENU_IMG_DIR="bootmenu.img.d"

BOOTMENU_CMD="/var/tmp/bootmenu.cmd"
BOOTMENU_SCR="$BOOTMENU_EMMC_DIR/bootmenu.scr"

BOOTMENU_DEFAULT="/etc/default/bootmenu.item"

BOOTMENU_NO_ATTACHED="0"

INT_CARD="1"
EXT_CARD="0"

HELP="0"

while test "$#" -gt 0; do
  case "$1" in
    -e|--emmc)
      BOOTMENU_EMMC_DIR="$2"
      shift
      ;;
    -c|--cfg)
      BOOTMENU_CFG_DIR="$2"
      shift
      ;;
    -b|--boot)
      BOOTMENU_BOOT_DIR="$2"
      shift
      ;;
    -o|--optboot)
      BOOTMENU_OPTBOOT_DIR="$2"
      shift
      ;;
    -d|--default)
      BOOTMENU_DEFAULT="$2"
      shift
      ;;
    -n|--no-attached)
      BOOTMENU_NO_ATTACHED="1"
      shift
      ;;
    -h|--help)
      HELP="1"
      ;;
    *)
      echo "Unknown option: $2"
      exit 1
      ;;
  esac
  shift
done

if test "$HELP" = "1"; then
  echo "This script generates U-Boot Bootmenu script $BOOTMENU_SCR"
  echo "and needed images in $BOOTMENU_EMMC_DIR/$BOOTMENU_IMG_DIR"
  echo "Bootmenu entries are read from config files stored in $BOOTMENU_CFG_DIR"
  echo
  echo "You need to run this script every time you install or uninstall"
  echo "kernel images in $BOOTMENU_BOOT_DIR, $BOOTMENU_OPTBOOT_DIR"
  echo "or when bootmenu config files in $BOOTMENU_CFG_DIR are changed"
  echo
  echo "To run this script, first eMMC partition must be mounted to"
  echo "$BOOTMENU_EMMC_DIR"
  echo
  echo "Options for custom paths:"
  echo "-e|--emmc        - path to mounted eMMC partition"
  echo "-c|--cfg         - path to cfg directory"
  echo "-b|--boot        - path to boot directory"
  echo "-o|--optboot     - path to optified boot directory"
  echo "-d|--default     - path to default symlink item"
  echo "-n|--no-attached - do not add attached kernel menu entry"
  echo "-h|--help        - show this help"
  echo
  echo "Supported filesystems for first eMMC partition:"
  echo "ext2 ext3 ext4 vfat"
  echo
  echo "Author: Pali Rohár <pali.rohar@gmail.com>"
  echo "License: GNU GPL v3"
  exit 1
fi

if ! mount | grep -q "$BOOTMENU_EMMC_DIR"; then
  echo "First eMMC partition $BOOTMENU_EMMC_DIR is not mounted!"
  exit 1
fi

type=$(mount | grep " $BOOTMENU_EMMC_DIR " | sed 's/.*type //;s/ .*//')
if test "$type" != "ext2" && test "$type" != "ext3" && test "$type" != "ext4" && test "$type" != "vfat"; then
  echo "First eMMC partition $BOOTMENU_EMMC_DIR must be ext2, ext3, ext4 or FAT32!"
  exit 1
fi

rm -f "$BOOTMENU_CMD"
rm -f "$BOOTMENU_CMD.new"
rm -f "$BOOTMENU_CMD.default"
rm -f "$BOOTMENU_SCR"
rm -rf "$BOOTMENU_EMMC_DIR/$BOOTMENU_IMG_DIR"
mkdir -p "$BOOTMENU_EMMC_DIR/$BOOTMENU_IMG_DIR"

count=0
default=""

# check for default entry
if test -f "$BOOTMENU_DEFAULT" && test -h "$BOOTMENU_DEFAULT"; then
  default="$(readlink -f $BOOTMENU_DEFAULT)"
  if ! test -f "$default"; then
    default=""
  else
    echo "Default bootmenu entry is '$default'"
    count=$(($count+1))
  fi
fi

# add entry for attached kernel
if test "$BOOTMENU_NO_ATTACHED" != "1"; then
  system="$(osso-product-info -q OSSO_PRODUCT_RELEASE_NAME 2>/dev/null || true)"
  kernel="$(zimage-get-version -f /dev/mtd3ro 2>/dev/null || true)"
  if test -z "$system" && test -z "$kernel"; then
    ITEM_NAME="Attached kernel"
  elif test -z "$system"; then
    ITEM_NAME="Attached kernel $kernel"
  elif test -z "$kernel"; then
    ITEM_NAME="$system with attached kernel (Internal Nand)"
  else
    ITEM_NAME="$system with attached kernel $kernel (Internal Nand)"
  fi

  echo "Adding bootmenu entry for: '$ITEM_NAME'"
  printf "setenv bootmenu_$count '$ITEM_NAME=run attachboot';" >> "$BOOTMENU_CMD"
  count=$(($count+1))
fi

for file in $BOOTMENU_CFG_DIR/*.item; do

  if ! test -f "$file"; then continue; fi

  echo
  echo "Configuration file: $file"

  ITEM_NAME=""
  ITEM_DEVICE=""
  ITEM_FSTYPE=""
  ITEM_KERNEL=""
  ITEM_INITRD=""
  ITEM_SCRIPT=""
  ITEM_CMDLINE=""
  ITEM_USEATAG="" # Obsoleted
  ITEM_REUSEATAGS="" # Obsoleted
  ITEM_OMAPATAG=""
  . $file
  mmcnum=""
  mmcpart=""
  mmctype=""
  mmckernfile=""
  mmcinitrdfile=""
  mmcscriptfile=""

  if test -z "$ITEM_NAME"; then
    echo "Error: Invalid file - missing name"
    continue
  fi

  if test -z "$ITEM_KERNEL" && test -z "$ITEM_SCRIPT"; then
    echo "Warning: Invalid file - missing kernel or script file - skipping..."
    continue
  fi

  if test "$ITEM_DEVICE" = "nand" || test "$ITEM_DEVICE" = "mtd5" || test "$ITEM_DEVICE" = "rootfs" || test -z "$ITEM_DEVICE"; then

    # kernel and initrd are on rootfs, need to convert to uimage format and store to eMMC

    # kernel and initrd images can be optified, check full path
    kernel_path=""
    initrd_path=""

    if test -f "$BOOTMENU_BOOT_DIR/zImage-$ITEM_KERNEL" || test -f "$BOOTMENU_OPTBOOT_DIR/zImage-$ITEM_KERNEL"; then
      ITEM_KERNEL="zImage-$ITEM_KERNEL"
    fi

    if test -f "$BOOTMENU_BOOT_DIR/$ITEM_KERNEL"; then
      kernel_path="$BOOTMENU_BOOT_DIR/$ITEM_KERNEL"
    elif test -f "$BOOTMENU_OPTBOOT_DIR/$ITEM_KERNEL"; then
      kernel_path="$BOOTMENU_OPTBOOT_DIR/$ITEM_KERNEL"
    else
      echo "Error: Kernel image '$ITEM_KERNEL' was not found in $BOOTMENU_BOOT_DIR or $BOOTMENU_OPTBOOT_DIR" >&2
      continue
    fi

    mmcnum="$INT_CARD"
    mmcpart="1"
    mmctype="$type"
    mmckernfile="$BOOTMENU_IMG_DIR/$ITEM_KERNEL"

    if test "$mmctype" = "vfat"; then
      mmctype="fat"
    elif test "$mmctype" = "ext3"; then
      mmctype="ext2"
    fi

    if ! test -z "$(mkimage -l $kernel_path 2>&1 1>/dev/null)"; then

      echo "Generating u-boot image for kernel '$ITEM_KERNEL'..."
      mkimage -A arm -O linux -T kernel -C none -a 80008000 -e 80008000 -n "$ITEM_KERNEL" -d "$kernel_path" "$BOOTMENU_EMMC_DIR/$BOOTMENU_IMG_DIR/$ITEM_KERNEL" >/dev/null

      if test "$?" != "0"; then
        echo "Error: Generating u-boot image for kernel '$ITEM_KERNEL' failed" >&2
        continue
      fi

    fi

    if ! test -z "$ITEM_INITRD"; then

      # we have also initrd

      if test -f "$BOOTMENU_BOOT_DIR/initrd-$ITEM_INITRD" || test -f "$BOOTMENU_OPTBOOT_DIR/initrd-$ITEM_INITRD"; then
        ITEM_INITRD="initrd-$ITEM_INITRD"
      fi

      if test -f "$BOOTMENU_BOOT_DIR/$ITEM_INITRD"; then
        initrd_path="$BOOTMENU_BOOT_DIR/$ITEM_INITRD"
      elif test -f "$BOOTMENU_OPTBOOT_DIR/$ITEM_INITRD"; then
        initrd_path="$BOOTMENU_OPTBOOT_DIR/$ITEM_INITRD"
      else
        echo "Error: Initrd image '$ITEM_INITRD' was not found in $BOOTMENU_BOOT_DIR or $BOOTMENU_OPTBOOT_DIR" >&2
        continue
      fi

      mmcinitrdfile="$BOOTMENU_IMG_DIR/$ITEM_INITRD"

      if ! test -z "$(mkimage -l $initrd_path 2>&1 1>/dev/null)"; then

        echo "Generating u-boot image for initrd '$ITEM_INITRD'..."
        mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n "$ITEM_INITRD" -d "$initrd_path" "$BOOTMENU_EMMC_DIR/$BOOTMENU_IMG_DIR/$ITEM_INITRD" >/dev/null

        if test "$?" != "0"; then
          echo "Error: Generating u-boot image for initrd '$ITEM_INITRD' failed" >&2
          continue
        fi

      fi

    fi

  else

    # kernel, initrd or script are on eMMC or SD card
    mmcnum="$(echo $ITEM_DEVICE | cut -f1 -dp)"
    mmcpart="$(echo ${ITEM_DEVICE}p1 | cut -f2 -dp)" # HACK: if ITEM_DEVICE has no part first is selected

    if test -z "$mmcnum" || test -z "$mmcpart"; then
      echo "Error: Incorrect device '$ITEM_DEVICE'" >&2
      continue
    fi

    if test "$ITEM_FSTYPE" = "fat" || test "$ITEM_FSTYPE" = "vfat"; then
      mmctype="fat"
    elif test "$ITEM_FSTYPE" = "ext2" || test "$ITEM_FSTYPE" = "ext3"; then
      mmctype="ext2"
    elif test "$ITEM_FSTYPE" = "ext4"; then
      mmctype="ext4"
    else
      echo "Error: Unknown filesystem '$ITEM_FSTYPE'" >&2
      continue
    fi

    if ! test -z "$ITEM_SCRIPT"; then
      mmcscriptfile="$ITEM_SCRIPT"
    elif ! test -z "$ITEM_INITRD"; then
      mmckernfile="$ITEM_KERNEL"
      mmcinitrdfile="$ITEM_INITRD"
    elif ! test -z "$ITEM_KERNEL"; then
      mmckernfile="$ITEM_KERNEL"
    fi

  fi

  if ! test -z "$ITEM_USEATAG"; then
    echo "Warning: Item file has obsolated option ITEM_USEATAG. Change it to ITEM_OMAPATAG"
    ITEM_OMAPATAG=$ITEM_USEATAG
  fi

  if ! test -z "$ITEM_REUSEATAGS"; then
    echo "Warning: Item file has obsolated option ITEM_REUSEATAGS. Change it to ITEM_OMAPATAG"
    ITEM_OMAPATAG=$ITEM_REUSEATAGS
  fi

  rm -f "$BOOTMENU_CMD.new"

  echo "Adding bootmenu entry for: '$ITEM_NAME'"
  printf "setenv bootmenu_$count '$ITEM_NAME=" >> "$BOOTMENU_CMD.new"

  printf "setenv mmcnum $mmcnum;" >> "$BOOTMENU_CMD.new"
  printf "setenv mmcpart $mmcpart;" >> "$BOOTMENU_CMD.new"
  printf "setenv mmctype $mmctype;" >> "$BOOTMENU_CMD.new"

  if test -z "$mmcscriptfile" && ! test -z "$ITEM_CMDLINE"; then
    printf "setenv bootargs $ITEM_CMDLINE;" >> "$BOOTMENU_CMD.new"
  else
    printf "setenv bootargs;" >> "$BOOTMENU_CMD.new"
  fi

  if test -z "$mmcscriptfile" && ! test -z "$ITEM_OMAPATAG"; then
    printf "setenv setup_omap_atag 1;" >> "$BOOTMENU_CMD.new"
  else
    printf "setenv setup_omap_atag;" >> "$BOOTMENU_CMD.new"
  fi

  if ! test -z "$mmcscriptfile"; then
    printf "setenv mmckernfile;" >> "$BOOTMENU_CMD.new"
    printf "setenv mmcinitrdfile;" >> "$BOOTMENU_CMD.new"
    printf "setenv mmcscriptfile $mmcscriptfile;" >> "$BOOTMENU_CMD.new"
    printf "run trymmcscriptboot;" >> "$BOOTMENU_CMD.new"
  elif ! test -z "$mmcinitrdfile"; then
    printf "setenv mmckernfile $mmckernfile;" >> "$BOOTMENU_CMD.new"
    printf "setenv mmcinitrdfile $mmcinitrdfile;" >> "$BOOTMENU_CMD.new"
    printf "setenv mmcscriptfile;" >> "$BOOTMENU_CMD.new"
    printf "run trymmckerninitrdboot;" >> "$BOOTMENU_CMD.new"
  elif ! test -z "$mmckernfile"; then
    printf "setenv mmckernfile $mmckernfile;" >> "$BOOTMENU_CMD.new"
    printf "setenv mmcinitrdfile;" >> "$BOOTMENU_CMD.new"
    printf "setenv mmcscriptfile;" >> "$BOOTMENU_CMD.new"
    printf "run trymmckernboot;" >> "$BOOTMENU_CMD.new"
  else
    echo "Error: Unknown action" >&2
  fi

  printf "';" >> "$BOOTMENU_CMD.new"

  if test "$default" = "$file" && ! test -f "$BOOTMENU_CMD.default"; then
    echo "Configuring this bootmenu entry as default"
    sed 's/^setenv bootmenu_[0-9]*/setenv bootmenu_0/' "$BOOTMENU_CMD.new" > "$BOOTMENU_CMD.default"
  else
    cat "$BOOTMENU_CMD.new" >> "$BOOTMENU_CMD"
    count=$(($count+1))
  fi

  rm -f "$BOOTMENU_CMD.new"

done

# add last entry
printf "setenv bootmenu_$count;" >> "$BOOTMENU_CMD"

# if problems add some default entry
if test -f "$BOOTMENU_DEFAULT" && test -h "$BOOTMENU_DEFAULT" && ! test -f "$BOOTMENU_CMD.default"; then
  echo
  echo "Configuring attached kernel as default bootmenu entry"
  printf "setenv bootmenu_0 'Attached kernel=run attachboot';" > "$BOOTMENU_CMD.default"
fi

if test -f "$BOOTMENU_CMD.default"; then
  cat "$BOOTMENU_CMD.default" "$BOOTMENU_CMD" > "$BOOTMENU_CMD.new"
  mv "$BOOTMENU_CMD.new" "$BOOTMENU_CMD"
fi

echo
echo "Generating u-boot bootmenu script..."
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu -d "$BOOTMENU_CMD" "$BOOTMENU_SCR" >/dev/null

if test "$?" != "0"; then
  echo "Error: Generating u-boot bootmenu script failed" >&2
  exit 1
fi

rm -f "$BOOTMENU_CMD"
rm -f "$BOOTMENU_CMD.new"
rm -f "$BOOTMENU_CMD.default"


返回上一頁