How to extract and repack a Lg MS450H firmware
This article depicts the procedure to generate a custom firmware for Lg MS450H/MS400H device based on Realtek RTD1183 chipset. This is adapted and extracted from Astone forum, thanks to them.
Before starting, this blog disclaims any responsibility for any damage resulting from downloading or carrying out procedures depicted on this blog.
Prerequisites:
- Linux Distribution (for example Ubuntu or Arch)
- squashfs 3.0 (It has to be version 3.0 for firmware packing to work properly, otherwise generated squashfs image file will not work) , manual download
- zlib-dev installed (otherwise squashfs compilation will fail)
- a MS400H stock firmware to customise (I let you to find it on the web)
Firmware Extraction:
#Become root. Could work if working as normal user. Will verify this later. For now, root.
su
#Go to root directory and create a few directories
cd /root
mkdir ms450h
mkdir ms450h/tools
mkdir ms450h/previous
mkdir ms450h/current
mkdir ms450h/FINAL-PRODUCT
#Download squashfs 3.0 and extract
cd ms450h/tools
wget http://sourceforge.net/projects/squashfs/files/squashfs/squashfs3.0/squashfs3.0.tar.gz/download
gunzip squashfs3.0.tar.gz
tar -xvf squashfs3.0.tar
#Try to compile it. If make command doesn't work, install the gcc compiler with command
# apt-get install build-essential
cd squashfs3.0/squashfs-tools
make
#unsquashfs and mksquashfs should be there if compiled correctly
ls -al
#move them to tools directory
mv unsquashfs mksquashfs ../../
#go to tools directory and test them
#mksquashfs should show version 3.0
cd ../../
./unsquashfs
./mksquashfs -version
#Copy the original firmware to the "previous" folder
cd ../previous/
cp /your_firmware_path/your_firmware_name install.img
#Check file type with file cmd: Is it a tar archive?
file install.img
../../previous/MS400_091209_0118.img: POSIX tar archive (GNU) |
#List image file content
tar -tf install.img
IMAGE_SWUG_BAR_1.bmp IMAGE_SWUG_BAR_2.bmp IMAGE_SWUG_BAR_3.bmp IMAGE_SWUG_BAR_4.bmp IMAGE_SWUG_BG.bmp arial.ttf configuration.xml flash_erase install_a mkfs.jffs2 nandwrite package1/ package1/bluecore.video.lzma package1/usr.local.etc.tar.bz2 package1/bluecore.audio.lzma package1/squashfs1.img package1/vmlinux.develop.avhdd.libra.ms400.bin.lzma video_firmware.install.bin |
#Move to current directory and extract firmware
cd ../current/
tar -xvf ../previous/install.img
#Have a look at the xml installation file
more configuration.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> <packageFile> <info> <company>LG Electronics</company> <description>MS400 image file</description> <version>20091209C</version> <releaseDate>12/09/09 18:34</releaseDate> <signature>RTD1183</signature> </info> <installerAP> <fileName>install_a</fileName> </installerAP> <package> <info> <description>MS400-NOR</description> <version>0128</version> </info> <flash> <image type="linuxKernel"> <fileName>package1/vmlinux.develop.avhdd.libra.ms400.bin.lzma</fileName> <targetAddress>0x80100000</targetAddress> <version>N/A</version> </image> <image type="audioKernel"> <fileName>package1/bluecore.audio.lzma</fileName> <targetAddress>0x81b00000</targetAddress> <version>N/A</version> </image> <image type="videoKernel"> <fileName>package1/bluecore.video.lzma</fileName> <targetAddress>0x81d80000</targetAddress> <version>N/A</version> </image> <image type="squash"> <fileName>package1/squashfs1.img</fileName> <mountPoint>/</mountPoint> <version>N/A</version> </image> <image type="jffs2"> <fileName>package1/usr.local.etc.tar.bz2</fileName> <sizeBytesMin>0x100000</sizeBytesMin> <mountPoint>/usr/local/etc</mountPoint> <version>N/A</version> </image> </flash> </package> </packageFile> |
#it's NOR so we're only interested in package1 directory
#What's in package1?
cd package1/
ls -al
#First, usr.local.etc.tar.bz2. Straight forward enough
#A few important config files to be mounted at /usr/local/etc
mkdir usr-local-etc
cd usr-local-etc
tar -xvf ../usr.local.etc.tar.bz2
#list file content
ls -al
dvdplayer/ dvdplayer/script/ dvdplayer/script/start_1394 dvdplayer/script/run_tail dvdplayer/script/stop_1394 dvdplayer/dmem.bin group hdd hdd.old/ hdd.old/livepause/ hdd.old/root/ hdd.old/root/recovery/ hdd.old/root/lock/ hdd.old/fat32/ hdd.old/dvdvr/ ld.so.conf magic passwd profile rcS |
#List file space usage
du -h
16K ./dvdplayer/script 24K ./dvdplayer 4.0K ./hdd.old/dvdvr 4.0K ./hdd.old/root/lock 4.0K ./hdd.old/root/recovery 12K ./hdd.old/root 4.0K ./hdd.old/fat32 4.0K ./hdd.old/livepause 28K ./hdd.old 80K . |
#Now, look at the squashfs1
#Remember how we insisted on version 3.0 of squashfs?
cd ../
file squashfs1.img
squashfs1.img: Squashfs filesystem, little endian, version 3.0, 11574462 bytes, 1207 inodes, blocksize: 65536 bytes, created: Wed Dec 9 10:34:31 2009 |
#unsquash it
/root/ms450h/tools/unsquashfs squashfs1.img
created 873 files created 84 directories created 250 symlinks created 0 devices created 0 fifos |
#List package1 direcotry, a new folder squashfs-root is created
ls -al
# rename this new folder
mv squashfs-root/ squashfs1
#See what's inside unsquashed image
cd squashfs1
ls -al
total 112 drwxrwxr-x 13 ms400h-95 ms400h-95 4096 2009-12-09 10:34 . drwxr-xr-x 4 ms400h-95 ms400h-95 4096 2010-04-28 17:53 .. drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:47 bin drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:44 dev drwxr-xr-x 4 ms400h-95 ms400h-95 4096 2009-11-18 09:44 etc drwxr-xr-x 3 ms400h-95 ms400h-95 4096 2009-11-18 09:47 lib lrwxrwxrwx 1 ms400h-95 ms400h-95 11 2010-04-28 17:46 linuxrc -> bin/busybox drwxr-xr-x 7 ms400h-95 ms400h-95 4096 2009-11-18 09:44 mnt drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:44 proc drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:47 sbin drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:44 sys -rwxr-xr-x 1 ms400h-95 ms400h-95 61440 2009-07-07 14:04 Test.fat drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:44 tmp drwxr-xr-x 8 ms400h-95 ms400h-95 4096 2009-11-18 09:44 tmp_orig drwxr-xr-x 5 ms400h-95 ms400h-95 4096 2009-11-18 09:44 usr lrwxrwxrwx 1 ms400h-95 ms400h-95 4 2010-04-28 17:46 var -> tmp/ |
#List all files presents in squashfs image
find
#command result can be found here: Lg MS450H/MS400H squashfs image content
#display file space usage
du -h
4.0K ./mnt/hdc 4.0K ./mnt/hda 4.0K ./mnt/hdb 4.0K ./mnt/rd 4.0K ./mnt/hdd 24K ./mnt 4.0K ./sys 4.0K ./proc 4.0K ./tmp 4.0K ./dev 68K ./sbin 244K ./usr/sbin 292K ./usr/bin 680K ./usr/local/sbin 4.0K ./usr/local/lib 16K ./usr/local/etc/dvdplayer/script 24K ./usr/local/etc/dvdplayer 4.0K ./usr/local/etc/hdd.old/dvdvr 4.0K ./usr/local/etc/hdd.old/root/lock 4.0K ./usr/local/etc/hdd.old/root/recovery 12K ./usr/local/etc/hdd.old/root 4.0K ./usr/local/etc/hdd.old/fat32 4.0K ./usr/local/etc/hdd.old/livepause 28K ./usr/local/etc/hdd.old 80K ./usr/local/etc 4.0K ./usr/local/firmware 164K ./usr/local/bin/image/country 3.2M ./usr/local/bin/image 124K ./usr/local/bin/scripts 15M ./usr/local/bin/Resource/bmp 124K ./usr/local/bin/Resource/dtv_table 108K ./usr/local/bin/Resource/TT_Font 17M ./usr/local/bin/Resource 34M ./usr/local/bin 35M ./usr/local 36M ./usr 28K ./lib/modules/2.6.12.6-VENUS/kernel/net/ipv4 32K ./lib/modules/2.6.12.6-VENUS/kernel/net 44K ./lib/modules/2.6.12.6-VENUS/kernel/fs/isofs 60K ./lib/modules/2.6.12.6-VENUS/kernel/fs/ptp 520K ./lib/modules/2.6.12.6-VENUS/kernel/fs/ufsd 84K ./lib/modules/2.6.12.6-VENUS/kernel/fs/vcd 164K ./lib/modules/2.6.12.6-VENUS/kernel/fs/udf 876K ./lib/modules/2.6.12.6-VENUS/kernel/fs 44K ./lib/modules/2.6.12.6-VENUS/kernel/crypto 92K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/usb/host 28K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/usb/net 124K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/usb 308K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/net/wireless/realtek/11n8709/ieee80211 288K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/net/wireless/realtek/11n8709/HAL/rtl8192u 292K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/net/wireless/realtek/11n8709/HAL 604K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/net/wireless/realtek/11n8709 608K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/net/wireless/realtek 612K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/net/wireless 616K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/net 108K ./lib/modules/2.6.12.6-VENUS/kernel/drivers/scsi 852K ./lib/modules/2.6.12.6-VENUS/kernel/drivers 1.8M ./lib/modules/2.6.12.6-VENUS/kernel 1.9M ./lib/modules/2.6.12.6-VENUS 1.9M ./lib/modules 2.4M ./lib 20K ./etc/init.d 20K ./etc/reexec_init 92K ./etc 956K ./bin 4.0K ./tmp_orig/log/dvdplayer 8.0K ./tmp_orig/log 4.0K ./tmp_orig/lock/hotplug/mount_tmp 4.0K ./tmp_orig/lock/hotplug/rename_tmp 4.0K ./tmp_orig/lock/hotplug/convert_tmp 20K ./tmp_orig/lock/hotplug 4.0K ./tmp_orig/lock/subsys 28K ./tmp_orig/lock 4.0K ./tmp_orig/usbmounts 4.0K ./tmp_orig/www/adm 72K ./tmp_orig/www/cgi-bin 84K ./tmp_orig/www 4.0K ./tmp_orig/lib/hotplug 8.0K ./tmp_orig/lib 4.0K ./tmp_orig/ramfs/labels 4.0K ./tmp_orig/ramfs/volumes 12K ./tmp_orig/ramfs 148K ./tmp_orig 39M . |
#Explore content, but the files of interest are in etc and etc/init.d directories
ls -al etc
total 64 drwxr-xr-x 4 ms400h-95 ms400h-95 4096 2009-11-18 09:44 . drwxrwxr-x 13 ms400h-95 ms400h-95 4096 2009-12-09 10:34 .. -rw-r--r-- 1 ms400h-95 ms400h-95 340 2009-07-07 14:04 fstab lrwxrwxrwx 1 ms400h-95 ms400h-95 22 2010-04-28 17:46 group -> ../usr/local/etc/group -rw-r--r-- 1 ms400h-95 ms400h-95 6 2009-07-07 14:04 hostname -rw-r--r-- 1 ms400h-95 ms400h-95 20 2009-07-07 14:04 hosts -rw-r--r-- 1 ms400h-95 ms400h-95 385 2009-07-07 14:04 httpd.conf -rw-r--r-- 1 ms400h-95 ms400h-95 460 2009-07-07 14:04 inetd.conf drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:44 init.d lrwxrwxrwx 1 ms400h-95 ms400h-95 28 2010-04-28 17:46 ld.so.cache -> ../usr/local/etc/ld.so.cache lrwxrwxrwx 1 ms400h-95 ms400h-95 27 2010-04-28 17:46 ld.so.conf -> ../usr/local/etc/ld.so.conf lrwxrwxrwx 1 ms400h-95 ms400h-95 14 2010-04-28 17:46 mtab -> ../proc/mounts lrwxrwxrwx 1 ms400h-95 ms400h-95 23 2010-04-28 17:46 passwd -> ../usr/local/etc/passwd lrwxrwxrwx 1 ms400h-95 ms400h-95 24 2010-04-28 17:46 passwd- -> ../usr/local/etc/passwd- lrwxrwxrwx 1 ms400h-95 ms400h-95 24 2010-04-28 17:46 profile -> ../usr/local/etc/profile drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:44 reexec_init lrwxrwxrwx 1 ms400h-95 ms400h-95 26 2010-04-28 17:46 resolv.conf -> /usr/local/etc/resolv.conf -rw-r--r-- 1 ms400h-95 ms400h-95 20373 2009-07-07 14:04 services -rw-r--r-- 1 ms400h-95 ms400h-95 8 2009-11-18 09:44 system_svn_version -rwxr-xr-x 1 ms400h-95 ms400h-95 1893 2009-07-07 14:04 udhcpc.script |
ls -al etc/init.d
total 24 drwxr-xr-x 2 ms400h-95 ms400h-95 4096 2009-11-18 09:44 . drwxr-xr-x 4 ms400h-95 ms400h-95 4096 2009-11-18 09:44 .. -rwxr-xr-x 1 ms400h-95 ms400h-95 76 2009-07-07 14:04 rcS -rwxr-xr-x 1 ms400h-95 ms400h-95 1633 2009-07-07 14:04 rcS1 -rwxr-xr-x 1 ms400h-95 ms400h-95 227 2009-07-07 14:04 S50inetd -rwxr-xr-x 1 ms400h-95 ms400h-95 2821 2009-07-07 14:04 syslog.rcS |
#Init files. rcS calls rcS1 then rcS1 calls /usr/local/etc/rcS
#But /usr/local/etc/rcS will be in writable flash.
#Therefore, we can tell our media what to run every time it boots by modifying /usr/local/etc/rcS
cd etc/init.d/
more rcS
#!/bin/sh /etc/init.d/rcS1>/dev/console& echo "Welcome to Realtek Linux" |
more rcS1
#!/bin/sh /bin/mount -a cp -a /tmp_orig/* /tmp cp -a /usr/local/etc/hdd.old /tmp/hdd grep -q SYSLOGDISK /sys/realtek_boards/system_parameters if [ $? = 0 ]; then /etc/init.d/syslog.rcS& fi #echo "Use Flash as root."& #/bin/mkdir -p /var/lib/hotplug #/bin/mkdir -p /var/log& #ln -s /usr/local/firmware /var/lib/hotplug/& # Start all init scripts in /etc/init.d # executing them in numerical order. # for i in /etc/init.d/S??* ;do # Ignore dangling symlinks (if any). [ ! -f "$i" ] && continue case "$i" in *.sh) # Source shell script for speed. ( trap - INT QUIT TSTP set start . $i ) ;; *) # No sh extension, so fork subprocess. $i start& ;; esac done # We need to direct standard output to /dev/console or the output of script rcS will disappear. /usr/local/etc/rcS>/dev/console& /bin/hostname -F /etc/hostname& /sbin/ifconfig lo 127.0.0.1 up& /sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo& #/bin/mkdir -p /tmp/usbmounts #/bin/mkdir -p /var/lock/hotplug/convert_tmp #/bin/mkdir -p /var/lock/hotplug/rename_tmp #/bin/mkdir -p /var/lock/hotplug/mount_tmp #mkdir -p /tmp/ramfs/volumes #mkdir -p /tmp/ramfs/labels #touch /var/lock/hotplug/volume_lock #cp /etc/init.d/config /var/lock/hotplug/ #/bin/rm -rf /tmp/usbmounts/*& #/bin/rm -rf /tmp/usbmounts/.*& #/sbin/modprobe venus1394& #/sbin/modprobe ehci-hcd #/sbin/modprobe ohci-hcd #/bin/touch /var/log/messages # I donot know why syslog cannot work well with below parameters. Kernel problem or uClibc problem? #/sbin/syslogd -p /tmp/.log -n -m 0& #/sbin/klogd -n& #/sbin/syslogd& #/sbin/klogd& |
Firmware Customization Example :
#You can make your modifications from now in the squashfs1 directory
#Get back to squashfs1 directory to add a few important bits
cd ../..
ls -al
#For example add a home for root
mkdir root
#the root file system is ready for packing
#don't need old image anymore, so let's move it
cd ../
mv squashfs1.img ../../previous/
#let's pack it!
/root/ms450h/tools/mksquashfs squashfs1 squashfs1.img
Creating little endian 3.0 filesystem on squashfs1.img, block size 65536. Little endian filesystem, data block size 65536, compressed data, compressed metadata, compressed fragments Filesystem size 11303.69 Kbytes (11.04 Mbytes) 30.22% of uncompressed filesystem size (37408.10 Kbytes) Inode table size 11998 bytes (11.72 Kbytes) 29.50% of uncompressed inode table size (40673 bytes) Directory table size 13030 bytes (12.72 Kbytes) 41.62% of uncompressed directory table size (31305 bytes) Number of duplicate files found 51 Number of inodes 1207 Number of files 873 Number of fragments 125 Number of symbolic links 250 Number of device nodes 0 Number of fifo nodes 0 Number of socket nodes 0 Number of directories 84 Number of uids 1 ms400h-95 (1000) Number of gids 0 |
#maybe it's not necessary, but let's fix squashfs1.img permissions anyway
chmod 777 squashfs1.img
#check if our newly created image agrees with the stock one (in this example, I did not modify anything, just repack the unpacked squashfs image...)
du -h squashfs1.img
du -h ../../previous/squashfs1.img
file squashfs1.img
squashfs1.img: Squashfs filesystem, little endian, version 3.0, 11574983 bytes, 1207 inodes, blocksize: 65536 bytes, created: Wed Apr 28 22:37:28 2010 |
file ../../previous/squashfs1.img
#move file system outside, don't need it anymore
mv squashfs1 ../../
#now, the usr-local-etc directory!
cd usr-local-etc/
#For kicks, let's make /usr/local/etc/rcS run a custom script every time it starts
#Use nano to edit it so that the end reads
# zinwell for samba usage
ln -s -f /usr/local/etc/private /var/private mkdir /var/locks #our custom startup script /usr/local/etc/runPMP.sh & |
#Also use nano to create our custom runPMP.sh script
nano runPMP.sh
#Just a basic working one will do. We can modify it later
#It's in writable flash after all
#Here's what it looks like
#!/bin/sh echo "It ran!" >> /tmp/runPMP.log |
#Make it executable
chmod +x runPMP.sh
#Check that all required files are there. All there? Let's pack it then!
ls -al
#Move old file
mv ../usr.local.etc.tar.bz2 ../../../previous
ls -al
#Pack our modified files into bzcat2 tar archive
#Careful! It's easy to mix it up
tar cvfj ../usr.local.etc.tar.bz2 *
dvdplayer/ dvdplayer/script/ dvdplayer/script/run_tail dvdplayer/script/stop_1394 dvdplayer/script/start_1394 dvdplayer/dmem.bin group hdd hdd.old/ hdd.old/dvdvr/ hdd.old/root/ hdd.old/root/lock/ hdd.old/root/recovery/ hdd.old/fat32/ hdd.old/livepause/ ld.so.conf magic passwd profile rcS runPMP.sh |
#Check new archive contents
cd ../
tar -tf usr.local.etc.tar.bz2
#The file structure must look something like above
#Move directory outside
#And we're ready for the final step: creating the firmware install.img!
mv usr-local-etc/ ../../
Firmware Packing:
#Go to directory current and do a final check on the files
cd /root/ms450h/current/
find
#Below is the list of the files. If they are all there, you're good to go.
.
./nandwrite
./package1
./package1/squashfs1.img
./package1/bluecore.audio.lzma
./package1/vmlinux.develop.avhdd.libra.ms400.bin.lzma
./package1/bluecore.video.lzma
./package1/usr.local.etc.tar.bz2
./video_firmware.install.bin
./IMAGE_SWUG_BAR_3.bmp
./mkfs.jffs2
./configuration.xml
./arial.ttf
./flash_erase
./IMAGE_SWUG_BAR_4.bmp
./IMAGE_SWUG_BAR_2.bmp
./install_a
./IMAGE_SWUG_BAR_1.bmp
./IMAGE_SWUG_BG.bmp
#Finally, we get to create our final product!
tar cvf ../FINAL-PRODUCT/install.img *
#Check against the stock firmware
cd ..
file FINAL-PRODUCT/install.img
file previous/install.img
tar tf FINAL-PRODUCT/install.img
tar tf previous/install.img
du -h FINAL-PRODUCT/install.img
du -h previous/install.img
If all is good, flash the file install.img in FINAL-PRODUCT and hope it doesn't brick your media player (which you can easily recover with another cold flash anyway, see Cold Flash Procedure for MS450H ).