Showing posts with label computer. Show all posts
Showing posts with label computer. Show all posts

30 January 2011

Real hackweek, protected hackweek and long hackweek

I have been using KVM a lot, but never took time to understand how kvm works. I used some time from this hackweek to get rid of that regret.

Virtual Machine eXtensions instructions allow trap-and-emulate virtualization. And KVM exposes VMX in a convenient way to userspace in Linux. Virtual Machine Monitors(VMM) like qemu-kvm use the KVM API exposed by linux to emulate virtualize software.

x86_64 processors boot in real-mode. In this mode it can use only 16-bit addresses, ie., upto 1MByte RAM. The execution would begin at physical address 0xFFFFFFF0. Then the software has to switch to protected mode where protection and paging is possible. Paging is optional, but almost all OSes use demand paging extensively. Now 4 GBytes of linear address space is used. And then CPU can be switched to long mode i.e., 64-bit mode. Paging should be disabled in 32-bit mode, before switching to long mode. There are also other modes of operation like virtual-8086 mode to allow executing legacy real-mode software from protected mode, SMM for OS transparent execution of OEM specific code.

I had limited time and very very limited skill at hand. So aiming for the sky was not an option. Hence wrote a very simple VMM that directly starts the guest at address 0H, in 32-bit protected mode with paging disabled. And supports only insb and outsb as the only form of interaction possible for the guest. The guest is a simple static linked 32-bit program that doesn't use any library, and linked to start from 0x0. The guest simply reads a byte using insb and sends byte+1 back via outsb. The guest would halt, when it gets the, "Answer to the Ultimate Question of Life, the Universe, and Everything". The VMM reads the byte value to pass to the guest from stdin and prints its response in stdout.

The KVM API is really very easy to understand and use. But some knowledge of the processor was required to make use of it. Intel manuals helped there. I don't have good understanding of things yet, but something is better than nothing.

I was occupied by quite a lot of things in life and work in the recent past. So I wasn't really planning to participate and make this a real hackweek. Also a National holiday for Republic day of India, bang in the middle of the week prevents this hackweek from being a long hackweek! But seeing videos of my colleagues from various parts of world having fun, I couldn't resist and decided to go for the virtual hackweek. I thank my employer for giving me this protected hackweek, and let me learn/do things protected from everyday work.

13 June 2010

Hackweek V


I had been toying with the idea that, to split a file on my hard-disk, I have to read and write to a new file and then truncate the old file. But isn't it lots of unnecessary I/O. I already have all the data on disk. I should be able to change the meta-data alone and mark the file contents after some length as a different file.

So during this hackweek, I implemented 2 system calls on Linux, sys_split and sys_join. And added support for these calls to the FAT file-system. http://lkml.org/lkml/2010/6/9/200 With this patch one can split a file into 2 or join 2 files without doing much I/O!

Why FAT?
Normally creating a new file and then truncating a file approach, needs temporary free space as well. I once had a need to split files when there was no free space available. On advanced filesystems, sparse-file support(i.e., files with holes) helped. But FAT does not support sparse files. Also I wanted these to work on thumb drives which are mostly formatted as FAT32.

SLE11 SP1 release
This Hackweek was scheduled to follow the release of SLE11 SP1. And all the Bangalore employees, who worked for SLE11 SP1 were given a portable 160 hard-drive as a gift in the middle of hackweek. The transcend disk has a one-touch back up button, which works to sync selected folders, using a proprietary software available only on Windows. No support in Linux or Mac.

gnireenignE one-touch button

I thought, if the button press could be detected, I could use it to unmount the disk! So I set out to reverse engineer it. Usbmon + KVM + windows XP. Got the usbmon traces. I was expecting to see a simple Interrupt endpoint. But it was a bulk end-point only interface. And the software was continuously polling to get the button status. It was quite interesting to decipher the USBS and USBC's, but the SCSI/ATAPI payload had an unknown command DFh. And I assumed that by sending the command, if a button had been pressed in between, I would get a different value. And was trying hard for hours. But failed. Then took few more traces using Windows. Tried hard. When I almost gave up, I found couple of return bytes slightly different! Voila. The return value is different, only if the button is held down during the command. Now, I have a script to sync/unmount with a one-touch button! If you have this device, you can modify the script to do what ever you want it to do. Let your creativity flow freely.

05 April 2010

Who is Linux?

Yesterday, I was bored in the afternoon and had a digital camera with me. I thought of making my own steadicam, but then when I saw the tux over my TV, this contest came to my mind. And the result is an entry to the competition.

I spent only few minutes. I think it is quiet OK, given its very low production value. I am not trying to win, but just like I send crappy patches to Linux and waste kernel developers time, I uploaded it to waste 43 seconds of your time.

08 July 2009

Atomic git

As I wrote in git-pull-mishap-and-git-clean, the problem with git is that, operations are non-atomic. For example, if a git-pull is interrupted, or fails due to lack of disk space or network problem, the resulting repository will be in an in between state. This is problematic. It would be nice if git operations are atomic, in this sense.

A solution could be to have the git repository inside another git repository. For example, have the linux-2.6.git repo inside another git repo, say git-o-git. When you do a pull in linux-2.6.git, and if it succeeds do a `git commit -a` in the outer git-o-git. If it fails for some reason, one can go back to previous version of linux-2.6.git repo by doing a `git clean -d -f` and `git checkout -f` in the outer git-o-git.

It should be possible to add wrapper scripts to `git` and do this auto magically. May be it could be called as git WC, as it is built on top of git porcelain, which is built on top of git plumbing commands. ;-)

Has anyone tried this already?

GIT pull mishap and git clean

When I was doing a `git pull` from a remote repo, I ran out of disk space, which resulted in errors like

Updating ce8a742..faf80d6
error: git checkout-index: unable to write file drivers/usb/gadget/s3c-hsotg.c
error: git checkout-index: unable to write file drivers/usb/gadget/u_audio.c
error: git checkout-index: unable to write file drivers/usb/gadget/u_audio.h


Freed some disk space and re-ran the `git-pull`. But it failed saying

$ git pull
Updating ce8a742..faf80d6
error: Untracked working tree file 'Documentation/ABI/testing/sysfs-bus-pci-devices-cciss' would be overwritten by merge.


Some of the files were created by the previous pull, but they are considered untracked files as the previous pull failed. `git pull -f` didnt help as git was reluctant to delete my untracked files.

Deleting huge list of files one by one was a pain. I was thinking of doing a git status to get the list of untracked files and deleting them. But Jony rescued me by telling me about `git clean` which can delete all the untracked files!

But I would really like to see a way to pull/checkout and over-write the untracked files, so that other untracked files, which will not be over-written, need not be deleted. Is there a way to do it?

01 April 2009

Type checking macros

#define to_cpumask(bitmap)                                              \
((struct cpumask *)(1 ? (bitmap) \
: (void *)sizeof(__check_is_bitmap(bitmap))))
static inline int __check_is_bitmap(const unsigned long *bitmap)
{
return 1;
}


The above macro is nothing but just
#define to_cpumask(bitmap) (struct cpumask *)(bitmap)

But it also does a compile-time checking that the parameter passed is of type
(const unsigned long *). If it is defined as an function all these ugly magic is not
needed. But a function cannot be used as a static initializer. Try declaring a variable,
static int a = printf("ok");
and one would get an error, "Initializer element is not constant".

I really wonder whether gcc might one day optimize out your type-checking call to the unused
function in tha above macro?! A solution could be providing an official gcc extension to assert types?!
Also the above code compiles fine without sizeof constification as well i.e., just return a void * from the
__check_is_bitmap() and remove the sizeof and casting.

I found the above code in the linux kernel. See http://lkml.org/lkml/2009/3/25/22
for the discussion. Even the ubiquitous printf, printk or any vararg code does not check for types. So
I wonder whether kernel developers need such tricky^Wugly code just for type checking, given that
the callers would likely read the definition of the macro as well. It is not a closed api.

Any other project uses such type-checking macros?

10 March 2009

Leanux - Running Linux on FAT just for fun

Most of the flash devices assume that fat is the only file-system. And there are plenty of electronic devices that run linux on fat. So just to know what it is to run linux on vfat, I tried it myself.

The openSUSE 11.1 installer wont allow you to partition the root as vfat. So I made 2 partitions, one ext3 and one vfat. Installed on ext3. Copied the whole partition to fat. I copied original files in place of symbolic links. Added vfat filesystem module to initrd . Modified grub boot from the fat partition with init=/bin/bash.

FAT's lack of support for posix file-permissions. was easy to overcome by mounting with all permissions to everyone, without users or noexec. It doesn't support symlinks, and special files. mknod will fail. But /dev is a tmpfs and it just copies the persistent files from /dev to the tmpfs on boot, instead of copying I created fresh device files in tmpfs. `mount` failed trying lock the file /etc/mtab. Mounting with -n worked. I guess plenty of things would fail if I try to run a proper desktop on FAT as it is.

I booted only to /bin/bash. When I tried doing a "exec init 1", it complained something like cannot remove /var/run/do_confirm. I didn't proceed further. This was a fun way to kill time while getting some insight of the booting process.

03 March 2009

Perceived Code-base quality

Recently one of my friend was re-orged from a open-source product to a proprietary project. He was complaining about the quality of the code-base, especially about using hard-coded paths and the likes.

I have also worked on different code-bases of different quality. And I feel that not being very confident about the quality helps at times. For example, say if you work on Linux Kernel and believe that the kernel code is of highest quality. When a bug is filed, you won't be confident of finding the bug in the kernel code. So one would look elsewhere like the setup or other layers or the application or wont even trust the bug-submitter.

Wouldn't a bug-hunter be happy and confident if he believes that there are lots of bugs in the code-forest to be hunted. But at the same time, if one is planning to do agriculture(more code changes, features, clean-ups etc...) in the same code-forest, one would be worried that his crops may be destroyed by some of those bugs lurking out there. But a software engineer should be a farmer who enjoys hunting as well.

Farmer + Hunter+... == Software Engineer. Happy code farming^Wcoding and bug-hunting.

p.s: Yes it is easy to hunt that single bug if the code-base is clean. But a bad code-base could be a nightmare for the hunter. He would be hunting various other bugs in search of one. But don't you like the thrill?

07 October 2008

Letter from a software engineer to his boss who is a computer literate

I am no car mechanic
The Volkswagen beetle is popularly known as bug. But there is a very big difference between fixing the car and S/W. All the bug cars have a fixed/same design. So it is like, we have the fixed/bug-free code in hand, and there is a copy of modified/buggy car. The mechanic needs to find the diff and patch which is quiet mechanical compared to fixing S/W. S/W is like making each and every car with a different design, engine etc.. (It is because they do different things as opposed to cars which do the same thing). It is like different vehicles but way more in no(infinite to be precise) than flights, ships, cars, sub-marines, hower- crafts etc... put together. Then fixing it is find the flaw of the original itself. This needs skill.

I am not changing tyres
Buying a new tyre is may not be cheaper but easier than fixing the old one. Fixing bugs is not like changing flat tyres. Fixing bugs especially in source that you didn't code can be a very hard problem. It is impossible to generalize difficulty in solving bugs or adding features. So do not measure the work done by counting the number of features added or number of bugs fixed.

Train is not a type of car
Size matters but not the way it is used. Some bug fix might require just adding one char say making "<" as "<=". But the complexity might be more depending on the size of the project, reproducibility etc... That changing a smaller wheel of a train engine might be harder than changing a bigger F1 car's wheel. I think LOC of the whole project being fixed is more relevant than LOC changed.

I am also a manager
You should know how hard(!) it is to manage multiple people. But managing multiple headless people is even more difficult. Parallelism with shared data in s/w is a beast. If there are 3 people with 3 jobs, say Aswath has to dig, Billa has to drop the seed and Chiru fills the hole with sand. Managing people is easy because they learn and adapt. But software, if there is a race, Chiru might fill the hole before Billa plants the seed or even worse try to fill the hole that is not yet dug. IOW, the programmer has to think for all these people, but you manage people who can not only think for himself but for many others as well. But yes I manage people who are obedient ;) - but I do not ask them to do what they can't.

Not all tennis players are champions
Teaching Sania Mirza to get an ace against Sharapova is difficult than making her serve right without hitting the net or out. Usually performance issues are hard which you don't count at all as they are neither bugs nor features :(

Let us make Abhinav Bindhra captain of the Indian Cricket Team
Yes, you read it correctly. That is what most of the Indian-American software companies do. People from different game tries to be a captain of a very different team game. For a team to do reasonably well, the captain needs to be an expert in the same game. There are some games where the captain can be a non playing captain, but still the team would need an expert with great knowledge of the game. The games board can be run by some sports people need not from the same sport. But still sports people. As the level goes up, the need low-level knowledge fade. Remember, baseball is still different from Cricket. And some times people who are not even sportsmen are made the captain. Please play at least few games with us. Better Learn the game.