Make the modifications
From Eminent Opensource
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:
- scripts that download source packages, compile it and install it
- a work directory for temporary files
- 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:
- LDFLAGS has -EL flag
- no ./configure, but a copy of the makefile
- 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).
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:
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:
- nzbscript.sh
- Is called before starting nzbget
- sets up swap (needed for smooth operations, especially unpacking..)
- sets up /tmp/hddinfo with mount path of USB media
- starts /opt/init/nzbget.sh $1 &
- btscript.sh
- Is called before starting Transmission / web server
- Does not set up swap. (not needed, Transmission is not memory-hungry)
- Sets up /tmp/hddinfo with mount path of USB media.
- Starts /opt/init/nzbget.sh $1 &
- bt_pause_script.sh and bt_resume_script.sh
- These handle the pause/resume of Transmission during the playback of movies.
- Transmission can eat up a lot of resources. So we send it a pause command when playing video.
- 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:
- 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.
- 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.
- 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.
- 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!
