summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2018-02-26 13:47:29 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2018-06-12 10:31:14 +0200
commit09fde79ec840ef9021ddbc28a58e6b1234d9de8f (patch)
tree7ed8c66b8d23f6ca5956d3f3c20f8bd523dbde0d /tools
parentd55680993df9b6743506814d98b5cc1859828f8a (diff)
downloadrockbox-09fde79ec840ef9021ddbc28a58e6b1234d9de8f.tar.gz
rockbox-09fde79ec840ef9021ddbc28a58e6b1234d9de8f.tar.bz2
rockbox-09fde79ec840ef9021ddbc28a58e6b1234d9de8f.zip
Agptek Rocker: Add tools to work with OF update images
Original firmware update is provided as .upt file. This file is actually ISO9660 image containing uBoot, kernel image and UBIFS rootfs and additional control files. Installing bootloader means patching UBIFS rootfs image. Change-Id: Ica86d1189dc1d5f3131d2035d8b87c8d08ec36b5
Diffstat (limited to 'tools')
-rw-r--r--tools/agptek_rocker/Dockerfile50
-rw-r--r--tools/agptek_rocker/README46
-rw-r--r--tools/agptek_rocker/bootloader_install.sh129
-rw-r--r--tools/agptek_rocker/hiby_player.sh10
-rw-r--r--tools/agptek_rocker/update_update.py81
5 files changed, 316 insertions, 0 deletions
diff --git a/tools/agptek_rocker/Dockerfile b/tools/agptek_rocker/Dockerfile
new file mode 100644
index 0000000000..de6a234474
--- /dev/null
+++ b/tools/agptek_rocker/Dockerfile
@@ -0,0 +1,50 @@
+FROM debian:9
+
+WORKDIR /home/rb
+ENV HOME /home/rb
+
+# Install tools needed
+RUN apt-get update && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y \
+ build-essential \
+ git \
+ perl \
+ curl \
+ texinfo \
+ flex \
+ bison \
+ bzip2 \
+ gzip \
+ zip \
+ patch \
+ automake \
+ libtool \
+ libtool-bin \
+ autoconf \
+ libmpc-dev \
+ gawk \
+ python \
+ python-lzo \
+ python-setuptools \
+ mtd-utils \
+ xorriso && \
+ rm -rf /var/lib/apt/lists/*
+
+# Clone rockbox repository
+RUN cd /home/rb && \
+ git clone https://github.com/wodz/rockbox-wodz.git
+
+# Build cross toolchain (It takes quite long)
+RUN cd /home/rb/rockbox-wodz && \
+ git checkout agptek-rocker && \
+ ./tools/rockboxdev.sh --target=y
+
+# Install tools for unpacking ubifs
+RUN cd /home/rb && \
+ git clone https://github.com/jrspruitt/ubi_reader.git && \
+ cd /home/rb/ubi_reader && \
+ python setup.py install
+
+# Copy build script
+RUN cp /home/rb/rockbox-wodz/tools/agptek_rocker/bootloader_install.sh /usr/local/bin && \
+ chmod 755 /usr/local/bin/bootloader_install.sh
diff --git a/tools/agptek_rocker/README b/tools/agptek_rocker/README
new file mode 100644
index 0000000000..6b627698e5
--- /dev/null
+++ b/tools/agptek_rocker/README
@@ -0,0 +1,46 @@
+Steps needed to patch update.upt with rockbox bootloader are explained in
+bootloader_install.sh shell script. Process is quite involved and some
+custom tools are needed.
+
+
+For convenience Dockerfile is provided which prepares custom image based
+on debian 9 which has all the tools needed to work with Agptek Rocker update
+images.
+
+Basically image extends standard debian image by:
+1) Installing developer packages from stock debian
+2) Cloning https://github.com/wodz/rockbox-wodz.git
+3) Building custom cross toolchain
+4) Cloning and installing tools to work with UBIFS
+
+You first need to build image with:
+docker build . -t "agptek-dev"
+
+Then you can start container and work with update.upt.
+If you want to generate patched update image in automatic way:
+docker run --rm -it -v /path/to/dir/with/update.upt:/upt \
+-e UPT_DIR=/upt agptek-dev bootloader_install.sh
+
+Patched update.upt with rockbox bootloader and rockbox.zip should end up in
+specified directory.
+
+If you want to play around, hack something etc. you can run container in
+interactive mode:
+docker run -it -v /path/to/dir/with/update.upt:/upt \
+-e UPT_DIR=/upt agptek-dev bash
+
+
+Files in this directory:
+README - this file
+bootloader_install.sh - shell script documenting process of patching
+ agptek rocker update images
+
+update_update.py - little helper utility to patch update.txt
+ controll file
+
+hiby_player.sh - shell script called on player boot which
+ originally started music player application
+ and now it starts bootloader
+
+Dockerfile - file to build docker image with all needed
+ tools to play with agptek rocker files
diff --git a/tools/agptek_rocker/bootloader_install.sh b/tools/agptek_rocker/bootloader_install.sh
new file mode 100644
index 0000000000..487b8870ea
--- /dev/null
+++ b/tools/agptek_rocker/bootloader_install.sh
@@ -0,0 +1,129 @@
+#!/bin/sh
+
+[ -z "$UPT_DIR" ] && UPT_DIR=`pwd`
+cd $HOME
+
+# get sources
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 0: Get sources !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+[ -d "$HOME/rockbox-wodz" ] || git clone https://github.com/wodz/rockbox-wodz.git
+
+cd $HOME/rockbox-wodz
+
+# build bootloader
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 1: Build bootloader !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+
+[ -d "$HOME/rockbox-wodz/build" ] && rm -rf $HOME/rockbox-wodz/build
+git checkout agptek-rocker && \
+git pull && \
+mkdir $HOME/rockbox-wodz/build && cd $HOME/rockbox-wodz/build && \
+../tools/configure --target=240 --type=b && \
+make clean && \
+make && \
+cd $HOME
+
+# Extract update file (ISO9660 image) content
+# NOTE: Update process on device loop mount ISO image. Default behavior of mount
+# is to map all names to lowercase. Because of this forcing lowercase
+# mapping is needed when extracting
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 2: Extract upt file !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+[ -d "$HOME/iso" ] && rm -rf $HOME/iso
+mkdir $HOME/iso && \
+xorriso -osirrox on -ecma119_map lowercase -indev $UPT_DIR/update.upt -extract / $HOME/iso
+
+# Extract rootfs files. Preserve permissions (although this are wrong!)
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 3: Extract system.ubi !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+ubireader_extract_files -k -o $HOME/rootfs $HOME/iso/system.ubi
+
+# Copy rockbox bootloader
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 4: Copy bootloader !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+cp $HOME/rockbox-wodz/build/bootloader.elf $HOME/rootfs/usr/bin/rb_bootloader && \
+mipsel-rockbox-linux-gnu-strip --strip-unneeded $HOME/rootfs/usr/bin/rb_bootloader
+
+# Overwrite default player starting script with one running our bootloader
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 5: Modify startup script !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+cp $HOME/rockbox-wodz/tools/agptek_rocker//hiby_player.sh $HOME/rootfs/usr/bin/hiby_player.sh && \
+chmod 755 $HOME/rootfs/usr/bin/hiby_player.sh
+
+# Rebuild ubifs
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 6: Rebuild system.ubi !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+mkfs.ubifs --min-io-size=2048 --leb-size=126976 --max-leb-cnt=1024 -o $HOME/system_rb.ubi -r $HOME/rootfs && \
+mv $HOME/system_rb.ubi $HOME/iso/system.ubi
+
+# Fixup update.txt file with correct md5
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 7: Fixup update.txt !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+python $HOME/rockbox-wodz/tools/agptek_rocker/update_update.py $HOME/iso/update.txt
+
+# Rebuild .upt file
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 8: Rebuild upt file !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+xorriso -as mkisofs -volid 'CDROM' --norock -output $UPT_DIR/update_rb.upt $HOME/iso
+
+# Build rockbox.zip
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 9: Build rockbox application !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+cd $HOME/rockbox-wodz/build && \
+../tools/configure --target=240 --type=n && \
+make clean && \
+make && \
+make zip && \
+cp rockbox.zip $UPT_DIR/
+
+# Cleanup
+echo
+echo "!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!! STEP 10: Cleanup !!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+rm -rf $HOME/rockbox-wodz/build
+rm -rf $HOME/iso
+rm -rf $HOME/rootfs
+
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "! Building finished !"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo
+echo "You should find update_rb.upt and rockbox.zip in output directory"
+echo
+echo "1) Unzip rockbox.zip file in the root directory of SD card"
+echo "2) Copy update_rb.upt to the root directory of SD card"
+echo "3) Rename update_rb.upt to update.upt in SD card"
+echo "4) Select update firmware on device"
+echo
diff --git a/tools/agptek_rocker/hiby_player.sh b/tools/agptek_rocker/hiby_player.sh
new file mode 100644
index 0000000000..e40e84c987
--- /dev/null
+++ b/tools/agptek_rocker/hiby_player.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+mount /dev/mmcblk0 /mnt/sd_0 &>/dev/null || \
+mount /dev/mmcblk0p1 /mnt/sd_0 &>/dev/null
+
+killall rb_bootloader &>/dev/null
+killall -9 rb_bootloader &>/dev/null
+
+/usr/bin/rb_bootloader
+sleep 1
diff --git a/tools/agptek_rocker/update_update.py b/tools/agptek_rocker/update_update.py
new file mode 100644
index 0000000000..4fb7056d19
--- /dev/null
+++ b/tools/agptek_rocker/update_update.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+import os
+import sys
+import hashlib
+import argparse
+from collections import OrderedDict
+
+EQ = '='
+BLK_START = '{'
+BLK_END = '}'
+
+#name: {key: value, key: value}
+def parse(filename):
+ blocks = OrderedDict()
+ blk = None
+ key = None
+ value = None
+
+ with open(filename) as f:
+ # read all lines
+ for line in f:
+ # if line has '=' sign treat it
+ # as split symbol
+ if EQ in line:
+ key, value = line.split(EQ, 1)
+ key = key.strip()
+ value = value.strip()
+
+ if value == BLK_START:
+ # value on the right of '=' is '{'
+ # so this opens new block
+ blk = key
+ blocks[key] = OrderedDict()
+
+ elif value == BLK_END:
+ # value on the right of '=' is '}'
+ # this terminates block
+ blk = None
+
+ else:
+ # key = value inside block
+ blocks[blk][key] = value
+
+ # return parsed structure as dictionary
+ return blocks
+
+# write back internal representation into file
+def dump(tree, filename=None):
+ with open(filename, 'w') as f:
+ for blk in tree.keys():
+ f.write('\n%s={\n' % blk)
+ for key,value in tree[blk].items():
+ f.write('\t%s=%s\n' % (key,value))
+ f.write('}\n')
+
+if __name__=='__main__':
+ description = 'Update information in update.txt control file.'
+ usage = 'update_update.py filepath'
+
+ argp = argparse.ArgumentParser(usage=usage, description=description)
+ argp.add_argument('filepath', help='update.txt filepath to update contents of.')
+
+ if len(sys.argv) == 1:
+ argp.print_help()
+ sys.exit(1)
+
+ args = argp.parse_args()
+
+ # build config file representation
+ tree = parse(args.filepath)
+
+ dir = os.path.dirname(args.filepath)
+
+ # update all md5 sums
+ for blk in tree.keys():
+ filename = os.path.join(dir, os.path.basename(tree[blk]['file_path']))
+ with open(filename) as f:
+ tree[blk]['md5'] = hashlib.md5(f.read()).hexdigest()
+
+ # write back result
+ dump(tree, args.filepath)