Make the modifications

From Eminent Opensource

Jump to: navigation, search

Contents

Prepare: step 1

The official firmware has been unpacked in /home/user/EM7075/unpacked/2.00.13. First thing to do before making any modifications is to copy this directory:

cd /home/user/EM7075/unpacked
cp -r 2.00.13 2.00.13-custom

Note that due to the bug described earlier, the copy command returns an error while copying subdirectories of the 'osd' directory. Workaround for Ubuntu users:

cd /home/user/EM7075/unpacked
sudo cp -r 2.00.13 2.00.13-custom
sudo chown -R user 2.00.13-custom

and for non-Ubuntu users use su -c solution.

You're now ready to make modifications in /home/user/EM7075/unpacked/2.00.13-custom. You can modify files, delete them, overwrite them with your version. Text files, directories, executables, libraries.. it's up to you!

Modification 1: fix the bug

We already provided a work-around during unpacking and copying of the official firmware. Now let's fix this bug in your custom firmware:

 cd /home/user/EM7075/unpacked/2.00.13-custom
 chmod 0755 -R bin/osd

Prepare: step 2

We need to store three things:

  1. scripts that download source packages, compile it and install it
  2. a work directory for temporary files
  3. a result directory in which the packages are installed

Just do:

cd /home/user/EM7075/
mkdir compile_scripts work result

Compile template script

The EM7075 uses a powerful 500mhz MIPS, Little Endian CPU. Since the toolchain can be configured for multiple targets, it's best to use a script and edit that to ensure correct CFLAGS and LDFLAGS are used. You will always need to use at least CFLAGS="-EL " to get the correct binary files. During ./configure you often need to set the host and target platforms as well.

This section sets up a template script that will be copied for compiling libraries and executables.

cd /home/user/EM7075/compile_scripts
mkdir _Template
cd _Template
touch compile_template.sh
chmod +x compile_template.sh

Put the following lines in the compile_template.sh file:

#!/bin/sh

# Set variables
export CFLAGS="-EL -O2"
export CXXFLAGS="-EL -O2"
export CC="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-gcc" # sometimes needed -EL -O2 here as well
export CXX="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-g++" # sometimes needed -EL -O2 here as well
export PATH=/opt/Sourcery_G++_Lite/bin:$PATH
export AR="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ar"
export LDFLAGS=" -s -Xlinker -rpath /lib -Xlinker -rpath-link /opt/Sourcery_G++_Lite/lib/gcc/mips-linux-gnu/4.3.3/el" # sometimes -EL here required
export RANLIB="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ranlib"
export AS="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-as"
export LD="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ld"

# Cleanup previous compilations
rm -rf /home/user/EM7075/result/template
rm -rf /home/user/EM7075/work/template*

# Download source and configure, compile, install
cd /home/user/EM7075/work
wget http://www.template/template-1.0.tar.gz
tar -zxvf template-1.0.tar.gz
cd template-1.0
./configure --enable-shared --disable-static --prefix=/home/user/EM7075/result/template --host=i686-pc-linux-gnu --target=mipsel-linux-gnu --build=mipsel-linux-gnu # mipsel sometimes is mips, enable-shared or disable-static depends on your needs and ./configure options
make install

Compile example

In this example, we will compile unrar version 4.0.5.

cd /home/user/EM7075/compile_scripts
cp -r _Template unrar-4.0.5
cd unrar-4.0.5
mv compile_template.sh compile_unrar-4.0.5.sh

Now edit compile_unrar-4.0.5.sh to:

#!/bin/sh

# Set variables
export CFLAGS="-EL -O2"
export CXXFLAGS="-EL -O2"
export CC="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-gcc" # -EL -02
export CXX="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-g++" # -EL -02
export PATH=/opt/Sourcery_G++_Lite/bin:$PATH
export AR="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ar"
export LDFLAGS=" -EL -s -Xlinker -rpath /lib -Xlinker -rpath-link /opt/Sourcery_G++_Lite/lib/gcc/mips-linux-gnu/4.3.3/el"
export DESTDIR="/home/user/EM7075/result/unrar-4.0.5"
export RANLIB="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ranlib"
export AS="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-as"
export LD="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ld"

# Cleanup previous compilations
rm -rf /home/user/EM7075/result/unrar-4.0.5
rm -rf /home/user/EM7075/work/unrar*

# Download source and configure, compile, install
cd /home/user/EM7075/work
wget http://www.rarlab.com/rar/unrarsrc-4.0.5.tar.gz
tar -zxvf unrarsrc-4.0.5.tar.gz
cd unrar
cp /home/user/EM7075/compile_scripts/unrar-4.0.5/makefile /home/user/EM7075/work/unrar/makefile
make unrar
make install

Note specifics for unrar:

  1. LDFLAGS has -EL flag
  2. no ./configure, but a copy of the makefile
  3. added variable DESTDIR

This makefile contains:

COMPILE=$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES)
LINK=$(CXX)

WHAT=UNRAR

UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o
LIB_OBJ=filestr.o scantree.o dll.o

OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o smallfn.o global.o file.o filefn.o filcreat.o \
        archive.o arcread.o unicode.o system.o isnt.o crypt.o crc.o rawread.o encname.o \
        resource.o match.o timefn.o rdwrfn.o consio.o options.o ulinks.o errhnd.o rarvm.o \
        rijndael.o getbits.o sha1.o extinfo.o extract.o volume.o list.o find.o unpack.o cmddata.o

.cpp.o:
        $(COMPILE) -D$(WHAT) -c $<

unrar:  $(OBJECTS) $(UNRAR_OBJ)
        @rm -f unrar
        $(LINK) -o unrar $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)
        $(STRIP) unrar

install:
                        install -D unrar $(DESTDIR)/bin/unrar

There is no manual on how to compile a specific package. You're challenged to create scripts that work and must learn about compilation and linking to reach your goal.

Finally, you can run the script:

/home/user/EM7075/compile_scripts/unrar-4.0.5/compile_unrar-4.0.5.sh

Compiling dependencies

Libraries can be static (*.la) or dynamic (*.so). so is an abbreviation for shared object.

When an executable is linked dynamic to a library, the executable will contain everything from the library that it needs. You can run the executable on the device without the library being available on the device as well.

When an executable is linked static to a library, the executable will be smaller in size, but needs the library to run on the device.

When only one executable needs the library, you might want to use static linking. When multiple executables need the library, dynamic linking saves storage space.

You can compile the libraries yourself as is done in the following example, but you can also link to the already available libraries on the unpacked firmware (adopt compile script accordingly).

Example_compile_curl

Copy results to custom firmware

Unrar already exists in the official firmware (it is used by nzbget) so it is easy to update it:

cp /home/user/EM7075/result/unrar-4.0.5/bin/unrar /home/user/EM7075/unpacked/2.00.13-custom/opt/bin/

Notice that your unrar (compared to the one in the official 2.00.13 firmware) is a newer release (3.90 vs. 4.0.5), 3 times as fast, and 110kb smaller.

Optimizations

When you surf the Internet, you can find a lot of optimizations possible when compiling source code. But be aware: too much 'optimization' likely results in broken binaries.

Most famous optimizations are -Os (optimize for size) and -O2 (optimizing for speed).

A benchmark for 'unrar', a CPU and disk-intensive application, was performed by Martin Herrman (end-user) and Alex (Eminent development). Results are in the forum:

  1. compiler: optimize for size?
  2. unrar optimization

Eminent has planned this improvement for a future official firmware release.

Scripts information

The EM7075 uses several scripts which are called by the DMAOSD binary. Unfortunately you will not be able to adapt DMAOSD yourself, because it is based on a closed-source framework.

It calls the following scripts:

  1. nzbscript.sh
    1. Is called before starting nzbget
    2. sets up swap (needed for smooth operations, especially unpacking..)
    3. sets up /tmp/hddinfo with mount path of USB media
    4. starts /opt/init/nzbget.sh $1 &
  2. btscript.sh
    1. Is called before starting Transmission / web server
    2. Does not set up swap. (not needed, Transmission is not memory-hungry)
    3. Sets up /tmp/hddinfo with mount path of USB media.
    4. Starts /opt/init/nzbget.sh $1 &
  3. bt_pause_script.sh and bt_resume_script.sh
    1. These handle the pause/resume of Transmission during the playback of movies.
    2. Transmission can eat up a lot of resources. So we send it a pause command when playing video.
    3. We could consider pausing NZBget as well but it is not needed.

Lack of storage

One of the challenges will be the limited amount of storage available on the device. Read the documentation about packing your new custom firmware for details.

To limit the size of your files, use one of the following techniques:

  1. upx is an on-the-fly decompression tool for binaries (remember the 'doublespace' tool for MS-DOS?) Note: UPX can not be used on all binaries, it's a matter of trial and error.
  2. Opt.bin packages Unlimited amount of storage can be found on the external harddisk or usb-stick connected to your device. It is possible to create packages and put them on this external storage and have a script in your firmware being executed during boot, recognizing these packages and mounting them at a directory.
  3. strip Strip is an executable that comes with your compiler. It removes symbols from a binary that can be used for debugging. Usually you don't need that on your device and it is an easy way to save space. The compile template on this page strips the created binary.
  4. strip libs In order to keep our rootfs small, we can also strip debug information from libraires (.so) files. Remember to strip libs if you build newer version, and don't use strip all, just debug!
Personal tools