Thursday, April 5, 2012

Hacking JOSH - with virtual hardware

Posted by sudheera On 12:28 PM 16 comments



This post will extend the Hacking JOSH – Operating System Tutorial with some cool stuff. Some of the content of this post is based on the work done by Mr.Asiri Rathnayake.

Here I will show how to boot JOSH os in a virtual computer without using any hardware.(USB drive or floppy disk). Another advantage of using this method is you can develop and test it without rebooting your computer(host). All you need to do is rebooting the virtual computer.
_________________________________________________________
Preparatory Steps

1.Boot into your linux distro.
2.Install VirtualBox if you haven't installed it in your system already : download vbox
3.Install Netwide Assembler(nasm)
* You can check if it installed by executing the command nasm -version in the terminal and see if it produces any valid output
* If not, you can install nasm using the apt-get. (for ubuntu)
4.Install DOS File Utilities (dosfstools)
*check if the system already have  dosfstools by enter mkdosfs command.
5. Download kernel-3.0.asm and boot.asm files.
____________________________________________________
Compiling the Boot Loader and the Kernel

First of all you have to create a working directory and copy both kernel-3.0.asm and boot.asm files into it. My working directory is ~/exp/HACK_WITHOUT_USB .

Let's compile boot loader by executing following line.
nasm boot.asm -f bin -o boot.bin
Then the kernel.
nasm kernel-3.0.asm -f bin -o kernel.bin
Use the ls command and observe that there are two new files on the directory.
You can download boot.bin and kernel.bin here,only if you were unable to compile the source codes.
______________________________________________________
Creating the floppy image

We should use some kind of drive to boot up a computer, so we have to prepare a drive in a way it can do the job. Since here we're dealing with the virtual world we can create a image file of a disk instead of an actual disk.

The provided kernel code is designed to run from FAT12 media, like a floppy disk. So let's create a disk image with file system FAT12 and size 1.44MB.

File system structure of a floppy (source : http://arathnayake.files.wordpress.com/)



There are 2880 sectors. First one is the boot sector. Data Area is the one we're accessing from a file manager tool.(like windows explorer or nautilus)

Ok, Let's start work. Inside the working directory execute the following command.

dd if=/dev/zero bs=512 count=2880 of=./virtual_floppy.img
you should get a output like this


dd is a command use to copy or convert files. Here it copies from the special device at /dev/zero to the image file named virtual_floppy.img
with block size 512 up to 2880 sectors.


With above line we have allocated space for the floppy drive. Now we need to format it to FAT12.

/sbin/mkdosfs -F 12 virtual_floppy.img
________________________________________________________
Connecting the loop device with floppy image

Now we have the virtual floppy disk and we can easily mount it into a folder and copy the required files to it using GUI. But the problem is boot.bin file should be copied in to the boot sector, not to the data area.(look the file system structure above). So we connect this image file with a loop device and then using dd command we can save the boot.bin file inside of the boot sector. (this is the only method came in to my mind, If there are easier methods than this, please let me know)

Make the connection with device named loop0 inside the /dev directory by executing.
(you better execute sudo losetup -f and find out what loop device is free, it returns the first free loop device, In my case loop0 is free)
sudo losetup /dev/loop0 ./virtual_floppy.img

Format it so that we can mount the device in to a folder in order to copy the kernel.bin file.
sudo /sbin/mkdosfs -F 12 /dev/loop0
___________________________________________________________
Mount the floppy image to a folder
Before mount the device, we need to create a folder to mount it. Lets create a folder named virtual_floppy inside the /media directory (sorry, I have misspelled virtual :-) )
sudo mkdir /media/vitual_floppy

Then mount the device like this

sudo mount -o loop /dev/loop0 /media/vitual_floppy/

Now just copy the kernel.bin file.
sudo cp kernel.bin /media/vitual_floppy/

boot.bin file should be written in to the boot sector of the device loop0.
We can use dd command.
sudo dd if=./boot.bin of=/dev/loop0

We're almost finished with floppy image creating. we can now unmount the device and disconnect the image from the loop device.(This is not a must do step, but lets keep things neat)

sudo umount /media/vitual_floppy/

sudo losetup /dev/loop0 -d


___________________________________________________________
Add the disk image to the virtual computer's floppy drive


First create a virtual machine using vbox. Installing a OS to virtual machine is useless since we're trying to boot in to our own OS. :-)

Open virtualbox manager window by launching vbox. Right click on the virtual machine and then right click and select Settings.



Under the Storage tab click on the add controller button and select the add floppy drive. like this,



By clicking on the button with the + sign you can add the image file we created. After that you can start the virtual machine. you should enter the boot menu while booting and set the default boot drive to floppy. If everything went right you will end up with a screen like this.


This kernel can only execute two commands.
command ver prints the kernel version and the other one is exit .


Now the fun part begins. You can edit the kernel-3.0.asm file and compile it then copy it into the virtual_floppy.img. Finally boot from the updated kernel.

Each time you compile the source, it needs to repeat above procedure to copy the .bin file into the .img. It is pretty boring task to repeat the same thing again and again. But don't worry there is a simple solution.


You can write a shell script to do the job. Here's what I'm using >> download 
 (The script has been updated. Download the newer version - 1.39am, 7-Apr-2012
 [edited]
If you get error messages when executing the script please download the newer version.

Download the script from above link and copy it to the same directory where the virtual_floppy.img and two .bin files are stored in. Keep in mind that you don't need to compile the boot.asm each time. Just use the same boot.bin. Then in the terminal cd to the directory and just execute the command

sh kernel_update.sh
That's it. 

 Important :
       * File names should be boot.bin, kernel.bin and virtual_floppy.img  for using this script.(Or you can edit it)
       *If you duplicate virtual_floppy.img file and proceed above, then make sure the floppy drive of virtual box loaded with the newer copy of virtual_floppy.img before starting the virtual machine. 


Any issues with the tutorial? Please let me know if any. thank you


references :
http://asiri.rathnayake.org/articles/hacking-josh-operating-system-tutorial/
http://untitledfinale.wordpress.com/2007/10/09/create-mount-and-copy-floppy-disks-images-under-linux/#comment-62
http://en.wikipedia.org/wiki/Loop_device
http://linux.die.net/man/8/losetup


P.S -If you are getting a error like following while running above script please download this script.
A little delay added to the script before unmount the drive.


error: umount: /media/vitual_floppy: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
loop: can't delete device /dev/loop0: Device or resource busy







    16 comments:

    Great work machoo this is really helpful :)

    Sudheera, I got this problem while trying to run a virtual machine. Please see whether you know something to fix this.

    https://docs.google.com/open?id=0B0SvcTAspdLraVVMWUxRUTdiY2c

    @tharindu : Found the same problem and a simple solution for that.
    Just use "yum" instead of apt-get, execute the following commands as super user.
    yum install dkms gcc
    yum install kernel-headers kernel-devel
    'etc/init.d/vboxdrv setup'

    here's the link : Link

    And I don't have any idea why apt-get and yum gives different results. All I know is both of them can be used to install softwares and working in different levels. good luck..!!

    Thanx :) You gave me the solution to boot at last... When booting usb from my machine, it gives errors "System not found". I don't know why...

    In that video link, he uses Fedora, I guess. yum is just another package similar to apt-get, aptitude or synaptic in typical Ubuntu environment. It makes no difference for the problem. As far as it seems, the problem is with loading or locating the linux-kernel.

    බොහෝම ස්තූතියි..

    Thanks for sharing this effective article. I like the Idea. Great thinking! There is wonderful about "hacking josh-with virtual hardware". I am impressed by the quality of information on this website. There are a lot of good quality resources here. I am sure I will visit this place again soon. You can find some information with it.

    Post a Comment

    Please give your comments.