[Android Software/Hacking General [Developers Only]] iamsubhranil:
So here you come. To read and perform this tutorial, you obviously need a first hand experience on flashing a ROM and/or kernels. Otherwise this tutorial and my efforts to get you a device with two OSes running might end up giving you a bricked device. So, if you're hearing the terms "flashing" or 'kernels' for the first time and thinking it's kinda good food, then bro, just go and taste those first.

Something's to remind before we gonna dig deep into this tutorial->

Noone but you will be responsible for what you end up with.

The warranty of your device will be voided after this if it isn't already after rooting. For MI users, the good news is that you can reclaim it by just flashing the fastboot ROM for your device.

Enough lectures. Bro let's get to work.

Things you'll be needing =>

One working Windows PC(because I doesn't know any replacement of bootimg.exe on any other OS. If you know, then let me).

ADB, fastboot and the device drivers (easily found in XDA)

Any custom CWM based recovery installed.(since TWRP is most popular, I will demonstrate using it. You can use any other you want overall process will be the same)

A custom ROM and kernel for your phone(the second os)

A class 10 memory card ( I recommend 32GB for the spaces)

PART 1: MODIFYING THE BOOT

At first, how does your device boots up? What are the partitions called /data and /system? The answer is quite simple. It's your kernel that points out the location from where the OS should be picked up. So for booting into the second OS we need some modifications to it at first.

Search and download bootimg.exe on XDA, I'll post a link later. Create two folders. Name them "Internal OS" and "External OS" respectively. Put the zip file of the OS you're currently using to the first one and the OS you're gonna use on the external storage to the second one. Rename the second OS to originalExternalOS.zip. Extract originalExternalOS.zip. Pick the boot.img file from the root of the extracted folder and move it to a new folder named "boot2". Extract the IMG using bootimg.exe. Navigate to the initrd folder and you will get a file named 'fstab".

Basically it's the file that tells the kernel which partition does the OS resides in.

Open the file in your favourite text editor.

Replace every instance of the first line with the second one:

/dev/block/bootdevice/by-name/system => /dev/block/mmcblk1p2

/dev/block/bootdevice/by-name/userdata => /dev/block/mmcblk1p3

/dev/block/bootdevice/by-name/cache => /dev/block/mmcblk1p4

Save the file without giving any extension to it. Repack it using the same tool. You'll have boot-new.img and boot-old.img. Rename boot-new.img to boot.img and replace the one in the root folder with this. Basically what we're doing here is replacing the old boot.img with the modified one.

For your knowledge, blocks are the partitions of any storage you have on your device. For example, your internal storage is partitioned to near about 30 different blocks each starting with prefix "mmcblk0p". We here just told the kernel to load the OS from the blocks mentioned. We'll be creating these blocks in the external SD card next.

PART 2: PARTITIONING THE SD CARD

Connect your device with the memory card inserted to your PC. If you haven't installed fastboot, ADB, and the drivers, do it now.

READ THE FOLLOWING CAREFULLY

Reboot the device to recovery mode. Type the commands in cmd:

adb shell
parted
unit MB
print
quit
umount external_sd

Read and store the minimum and maximum capacity of your card. Since different cards will have different capacities I will point it as variable MIN_SIZE and MAX_SIZE. You'll need to calculate and put the values in the commands. Now type the following commands on cmd:

parted /dev/block/mmcblk1
rm 1

//START_BLOCK = MAX_SIZE - 5000

mkpartfs primary fat32 MIN_SIZE START_BLOCK

//SYS_START = START_BLOCK+1
//SYS_END = SYS_START + 1200

mkpartfs primary ext2 SYS_START SYS_END

//DATA_START = SYS_END+1
//DATA_END = DATA_START + 3500

mkpartfs primary ext2 DATA_START DATA_END

//CACHE_START = DATA_END + 1

mkpartfs primary ext2 CACHE_START MAX_SIZE

//We have partitioned the memory card. Let's format them. Ignore all "Do you wish to continue" question in the next commands as we're already mentioning yes.

mkfs yes 1 fat32
mkfs yes 2 ext2
mkfs yes 3 ext2
mkfs yes 4 ext2
quit

//Now they are almost ready. Just make the newly created blocks readable by the OS.

make_ext4fs /dev/block/mmcblk1p2
make_ext4fs /dev/block/mmcblk1p3
make_ext4fs /dev/block/mmcblk1p4

//Now you get where does the blocks come in the kernel right?

exit

//You've covered up the hardest part. Let's get some coffee.

PART 3: MODIFYING THE NEW OS

You've left the OS extracted in the "External OS" folder right? It's time to do some magic in it. We're gonna tell the OS to be installed in the blocks we created just like the kernel. But wait, where does the OS know before installing where it should get installed? Well, the answer hides in the updater-script in the folder META-INF > com > google > android. Navigate yourself in it. Open the updater-script file in your favourite editor ( I use notepad++ ) and modify it in the same way as the boot.

Replace every instance of the first line with the second one:

/dev/block/bootdevice/by-name/system => /dev/block/mmcblk1p2

/dev/block/bootdevice/by-name/userdata => /dev/block/mmcblk1p3

Leave the /dev/block/bootdevice/by-name/boot as it's the fundamental block and we can't replicate it. Don't think for the /cache partition as we've already done that in the boot.img file. Now navigate to the root of the folder where you extracted the External OS. Select all files, add them to a zip file using WinRAR. Name the file to newOS.zip. Open newOs.zip and originalExternalOS.zip with WinRAR and compare them if you find any change in the folder tree. They must and they should be exactly the same. You're 80% done.

PART 4: MODIFYING THE RECOVERY

We often flash many zips including very popular Xposed and other mods to our OS right? They also look for the /system partition. So what are we gonna do? Modifying each of them? Nah. Let's modify where they get which one the /system is. The recovery. Extract the img of the recovery you're using with the same bootimg.exe. Modify exactly the same things. I.e.

Replace every instance of the first line with the second one:

/dev/block/bootdevice/by-name/system => /dev/block/mmcblk1p2

/dev/block/bootdevice/by-name/userdata => /dev/block/mmcblk1p3

/dev/block/bootdevice/by-name/cache => /dev/block/mmcblk1p4

in the following files : initrd/fstab.qcom

initrd/etc/recovery.fstab

initrd/etc/twrp.fstab(For TWRP only)

Save them. Repack. And you got your recovery-new.img and recovery-old.img. Put recovery-new.img and newOS.zip in the same folder. Now wake up, it's time for some action.

PART 5 : INSTALLING THE OS

Open cmd in the folder where newOS.zip resides. Reboot the device in fastboot mode. Type the following commands:

adb push newOS.zip external_sd
fastboot flash recovery recovery-new.img
fastboot boot recovery

Now your device should boot up in recovery mode. To check if everything has gone fine mount system using TWRP. Use twrp's built in file manager and navigate to system folder. It's empty? Yup. You've done a great job. Now flash the newOS.zip using TWRP and your device should boot up in the new OS. To cross check again remove the SD card and try to boot. If you're headed towards recovery or bootloop after that then it's a win. Put the SD card back again and watch the new OS to boot.

PART 6: SWITCHING BETWEEN THE TWO

Extract the boot.img from the "Internal OS" zip file and put it together with recovery-old.img. To check if your old system is untouched type the following commands in fastboot mode:

fastboot flash recovery recovery-old.img
fastboot flash boot boot.img
fastboot boot system

Your device should take you back to the old one. Surprised? Now let's make a switch between the two. There are two methods.

METHOD 1: USING FLASHIFY

Create two folders in your SD card. Put boot.img and recovery-old.img to one and boot-new.img and recovery-new.img to the other. To switch to the external OS, just flash boot-new.img as boot and recovery-new.img using flashify. Ignore reboot now dialog and reboot directly to the system. To go back, first install flashify in the new OS and flash boot.img and recovery-old.img. Easy right?

METHOD 2: USING ZIPS

I'm gonna tell you that tomorrow as I can write no more today. :P

More to come....

CREDITS:

justzzshadz from MIUI forum for this revolutionary concept. [MENTION=6921532]iamsubhranil[/MENTION] for adding TWRP, Flashify support and completely rewriting the tutorial.