May 16

Linux File Systems: Ext2 vs Ext3 vs Ext4

Credits: The Geek Stuff

EXT2, EXT3 and EXT4 are all filesystems created for Linux. This article explains the following:

  • High level difference between these filesystems.
  • How to create these filesystems.
  • How to convert from one filesystem type to another.

Ext2

  • Ext2 stands for second extended file system.
  • It was introduced in 1993. Developed by Rémy Card.
  • This was developed to overcome the limitation of the original ext file system.
  • Ext2 does not have journaling feature.
  • On flash drives, usb drives, ext2 is recommended, as it doesn’t need to do the over head of journaling.
  • Maximum individual file size can be from 16 GB to 2 TB
  • Overall ext2 file system size can be from 2 TB to 32 TB

Ext3

  • Ext3 stands for third extended file system.
  • It was introduced in 2001. Developed by Stephen Tweedie.
  • Starting from Linux Kernel 2.4.15 ext3 was available.
  • The main benefit of ext3 is that it allows journaling.
  • Journaling has a dedicated area in the file system, where all the changes are tracked. When the system crashes, the possibility of file system corruption is less because of journaling.
  • Maximum individual file size can be from 16 GB to 2 TB
  • Overall ext3 file system size can be from 2 TB to 32 TB
  • There are three types of journaling available in ext3 file system.
    • Journal – Metadata and content are saved in the journal.
    • Ordered – Only metadata is saved in the journal. Metadata are journaled only after writing the content to disk. This is the default.
    • Writeback – Only metadata is saved in the journal. Metadata might be journaled either before or after the content is written to the disk.
  • You can convert a ext2 file system to ext3 file system directly (without backup/restore).

Ext4

  • Ext4 stands for fourth extended file system.
  • It was introduced in 2008.
  • Starting from Linux Kernel 2.6.19 ext4 was available.
  • Supports huge individual file size and overall file system size.
  • Maximum individual file size can be from 16 GB to 16 TB
  • Overall maximum ext4 file system size is 1 EB (exabyte). 1 EB = 1024 PB (petabyte). 1 PB = 1024 TB (terabyte).
  • Directory can contain a maximum of 64,000 subdirectories (as opposed to 32,000 in ext3)
  • You can also mount an existing ext3 fs as ext4 fs (without having to upgrade it).
  • Several other new features are introduced in ext4: multiblock allocation, delayed allocation, journal checksum. fast fsck, etc. All you need to know is that these new features have improved the performance and reliability of the filesystem when compared to ext3.
  • In ext4, you also have the option of turning the journaling feature “off”.

Use the method we discussed earlier to identify whether you have ext2 or ext3 or ext4 file system.

Warning: Don’t execute any of the commands given below, if you don’t know what you are doing. You will lose your data!

Creating an ext2, or ext3, or ext4 file system

Once you’ve partitioned your hard disk using fdisk command, use mke2fs to create either ext2, ext3, or ext4 file system.

Create an ext2 file system:

mke2fs /dev/sda1

Create an ext3 file system:

mkfs.ext3 /dev/sda1

(or)

mke2fs –j /dev/sda1

Create an ext4 file system:

mkfs.ext4 /dev/sda1

(or)

mke2fs -t ext4 /dev/sda1

Converting ext2 to ext3

For example, if you are upgrading /dev/sda2 that is mounted as /home, from ext2 to ext3, do the following.

umount /dev/sda2

tune2fs -j /dev/sda2

mount /dev/sda2 /home

Note: You really don’t need to umount and mount it, as ext2 to ext3 conversion can happen on a live file system. But, I feel better doing the conversion offline.

Converting ext3 to ext4

If you are upgrading /dev/sda2 that is mounted as /home, from ext3 to ext4, do the following.

umount /dev/sda2

tune2fs -O extents,uninit_bg,dir_index /dev/sda2

e2fsck -pf /dev/sda2

mount /dev/sda2 /home

Again, try all of the above commands only on a test system, where you can afford to lose all your data.

Mar 12

Java Serial Communication in OS X

Installing RXTX

RXTX consists of two parts: The Java extension library RXTXcomm.jar and the serial driver to be integrated with the operating system. Download and place following binaries in the ‘/Library/Java/Extensions’ folder to make them available to all users .

Also, if you are using an IDE such as Eclipse, you can opt to include them in your project instead. If your project is SerialTest  then locations would be:

  • SerialTest/lib/RXTXcomm.jar
  • SerialTest/librxtxSerial.jnilib

Don’t forget to include them in your build path.

 The Serial Port Name

On MacOS X serial devices have a ‘device file’ defined in /dev, and are of the form tty.* or cu.*. If you don’t see the one corresponding to your device then you probably don’t have the appropriate driver installed. Bluetooth devices and ‘USB to RS232′ all appear as serial devices. If you have device called /dev/tty.mydevice, then in the SimpleWrite.java file change the value of the ‘defaultPort’ variable.

Sample Application

This example shows how write a Java program to write out “Hello World” to a serial port or to a USB to serial converter. Before you start you will need to ensure that a suitable Java VM is installed

import java.io.*;
import gnu.io.*;
import java.util.*;

public class SimpleWrite {
    static Enumeration	      portList;
    static CommPortIdentifier portId;
    static String	      messageString = "Hello, world!";
    static SerialPort	      serialPort;
    static OutputStream       outputStream;
    static boolean	      outputBufferEmptyFlag = false;

    public static void main(String[] args) {
	boolean portFound = false;
	String  defaultPort = "/dev/tty.mydevice";

	if (args.length > 0) {
	    defaultPort = args[0];
	}

	portList = CommPortIdentifier.getPortIdentifiers();

	while (portList.hasMoreElements()) {
	    portId = (CommPortIdentifier) portList.nextElement();

	    if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {

		if (portId.getName().equals(defaultPort)) {
		    System.out.println("Found port " + defaultPort);

		    portFound = true;

		    try {
			serialPort =
			    (SerialPort) portId.open("SimpleWrite", 2000);
		    } catch (PortInUseException e) {
			System.out.println("Port in use.");

			continue;
		    }

		    try {
			outputStream = serialPort.getOutputStream();
		    } catch (IOException e) {}

		    try {
			serialPort.setSerialPortParams(9600,
						       SerialPort.DATABITS_8,
						       SerialPort.STOPBITS_1,
						       SerialPort.PARITY_NONE);
		    } catch (UnsupportedCommOperationException e) {}

		    try {
		    	serialPort.notifyOnOutputEmpty(true);
		    } catch (Exception e) {
			System.out.println("Error setting event notification");
			System.out.println(e.toString());
			System.exit(-1);
		    }

		    System.out.println(
		    	"Writing \""+messageString+"\" to "
			+serialPort.getName());

		    try {
			outputStream.write(messageString.getBytes());
		    } catch (IOException e) {}

		    try {
		       Thread.sleep(2000);  // Be sure data is xferred before closing
		    } catch (Exception e) {}
		    serialPort.close();
		    System.exit(1);
		}
	    }
	}

	if (!portFound) {
	    System.out.println("port " + defaultPort + " not found.");
	}
    }

}

Credit: wikipedia.org

Mar 24

Calculate SHA1 and MD5 in Java

If you need to calculate a hash function on a message, there is an existing API in Java that can do that for you. It isn’t perfect, but it is really easy to use and supports most of the popular hashing algorithms – MD5 and SHA1 among them. Without further ado check out the following code snippet that calculates both hashes for specified message:

import java.security.MessageDigest;
import java.util.Formatter;

public class HashFunctionTest {

    public static String calculateHash(MessageDigest algorithm,
            String message) throws Exception{

        algorithm.update(message.getBytes());

        byte[] hash = algorithm.digest();

        return byteArray2Hex(hash);
    }

    private static String byteArray2Hex(byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }

    public static void main(String[] args) throws Exception {
        String message = "elmurod talipov";

        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5  = MessageDigest.getInstance("MD5");

        System.out.println(calculateHash(sha1, message));
        System.out.println(calculateHash(md5, message));
    }
}

You can see in the code above we use Formatter class to print out the hash code as a human readable String – it’s a readable, but slow solution. If you need something faster you may use other ways to do byte[] to Hex String conversion.

Jan 15

Adding new locale to apk files

Credit goes to djmcnz from XDA.

Introduction

For the purposes of this post language information is stored in XML strings in files on the Android system. In the case of MIUI and these instructions we will be dealing with .apk files (applications).

Within the apk files is a resources directory (/res) and within this are various values directories, there is a default values directory (/res/values) and alternative language values directories (e.g. /res/values-DE and /res/values-IT).

If the rom is set to use it’s default language it will read values from /res/values although these may NOT be in English. In MIUI, all of the common Android ASOP values in /res/values are English.

If you select a different language in the ROM than the default then the appropriate values directory will be searched. If a suitable string that matches your language selection is found in the alternative /res/values-xx directory then that string will be used instead. If an alternative does not exist then the default will be used.

Example:

Code:

/res/values/strings.xml
<stop_button_text>Stop</stop_button_text>

/res/values-DE/strings.xml
<stop_button_text>Halt</stop_button_text>

/res/values-IT/strings.xml
<stop_button_text>Basta</stop_button_text>

In this example, if the language is set to the default the word “Stop” will be used, if it is set to German the word “Halt” will be substituted in, likewise “Basta” for Italian.

So, to add languages to a rom (or app) or to make an app multi-lingual you need to either change the default strings in /res/values/strings.xml to the ones you want to use or, and this is the preferable approach, add a /res/values-xx/strings.xml with the translations you want. The first approach will work (changing the default strings) but is not recommended because the Android Open Source Project and Android development in general, defaults to English. It’s best to use the built in language substitution capabilities of Android rather than to work around them. Indeed, if the MIUI devs actually added their strings in English to /res/values/strings.xml and the Chinese equivalents in the appropriate directory this rom would already be in English!

Adding Languages

To add a translation file (strings.xml) to an apk you need to:
- decode the apk
- create a language directory
- add the translation files
- recompile the strings
- add the new strings to the apk

Which all sounds a little daunting but it’s really quite straight-forward, rewarding when you see the result and a good way to understand how parts of Android work. Here’s how you can do it.

1. Decode the apk

You will need the excellent apktool from brut.all which you can get from the link below. apktool is relatively easy to use but includes some little tricks so you will need to read the wiki and thread about it.

Do NOT just post problems about apktool if you can’t get it to work. The tool DOES work so if it’s not decoding (or encoding) your apps correctly then you’re probably doing something wrong. If you start with this understand BEFORE you ask for support you’ll get a lot more help…

apktool: http://code.google.com/p/android-apktool/
wiki: http://code.google.com/p/android-apktool/w/list
thread: http://forum.xda-developers.com/showthread.php?t=640592

Please make sure you run the following command to include the MIUI framework in apktool. You only need to do this once for each framework. If apktool works with one rom and not the next then (re)install the framework for that rom.

Code:

 apktool if framework-res.apk 

Where framework-res.apk is the one from the rom you are working with. Make sure apktool can find (the correct) framework-res.apk before you run this command.

This thread is not for apktool support.

Now, before you proceed, decode a simple app from MIUI (such as updater.apk) using apktool, do not make ANY changes, then re-encode it using apktool. For example:

Code:

apktool d Updater.apk ./decoded/
apktool b ./decoded/ new_updater.apk

Use the -v (verbose) flag in apktool if you have problems and need to diagnose further.

Remember, Android uses a case-sensitive file system, make sure your capitalisation is correct.

Typically you will not be able to install this apk because it is not signed so if you want to test the process further you can now just try step 5 below using the two apks you have.

2. Create a language directory

Assuming you can decode/encode now, this is the easy bit. For your decoded app, navigate to the directory it was decoded in, then to the /res/ directory and simply create an empty directory for your language (e.g. /values-FR/) – use international naming conventions.

3. Add the translation files

Again, not too difficult this. Download the appropriate language file for your apk from the crowdin project linked below and, using the same structure as exists in /res/values/strings.xml create a new file called strings.xml in your alternative language directory (e.g. /res/values-ES/strings.xml).

The news strings.xml may contain as many or as few translations as you like. Remember, if a translation does not exist the default value from /res/values/strings.xml will be used.

Crowdin: http://crowdin.net/project/miui-rom-translation/invite

The xml formatting and tag names need to match exactly with the default strings.xml in /res/values although the translated file does NOT need to be complete.

It is worth remembering here that unless your source apk is already translated to English then some of the default values in /res/values/strings.xml will still be in Chinese, it would pay to check these.
4. recompile the strings
Now, if you’ve done everything carefully and correctly this step is really easy, all you need to do is recompile the apk with apktool using the b (for Build) switch.

Code:

 apktool b .// .apk 

If this throws errors or does not work then use the -v switch to turn on verbose mode and diagnose your problem. If you did the test in step #1 and it worked then any problem at this step is likely related to your news strings.xml. Back out the changes one by one until you have found the problem and try again.

If you simply can’t get it to compile with your changes then try just making a single change to the default strings.xml file in /res/values and see if that works for you.

Do NOT sign the apk!

5. Add the new strings to the apk

Easy. Open your new apk with a zip program (like 7Zip for Windows) and copy out the resources.arsc file in the root directory of the apk. Now take that file and copy it into the source apk from the rom overwriting the existing one. This process replaces the strings but keeps the integrity of the signatures on the files.

You can now push the modified file to your phone, replacing the stock one, reboot and you’re translated. Push the file using “adb push” or copy it into place using a root file manager, do not “install” the new apk. Make sure you put it in the correct place (replace the original) and reboot.

Conclusion

This process will help you add languages to any app including those in the MIUI rom. Because it’s a rom the strings are contained in many different apps as well as framework-res.apk. To completely translate the rom you will need to edit every apk that has strings in it.

You will need to do this every time an apk in the rom changes. If a new version is released and say launcher2.apk is changed but updater.apk is not, then you can retain your updater.apk but you’ll need to re-edit your launcher2.apk.

When an app changes the default strings.xml may also change. In this case you will need to make corresponding changes to your translations.

Good luck and if you get really stuck there’s lots of people in this that have achieved success and may be willing to help!