tech_log: November 2008

Saturday, November 22, 2008

Getting a nice penguin during boot (in qemu)

This is about enabling support in the kernal for nicer boot up screen.

Recompile kernel with following enabled in menuconfig:
Device Drivers -> Graphics support -> Framebuffer devices, and bellow will appear Bootup Logo - so, select it and recompile.

Checking qemu init

Here is a little tip I found on Busybox FAQ:

-----------

Busybox init isn't working!

Init is the first program that runs, so it might be that no programs are
working on your new system because of a problem with your cross-compiler,
kernel, console settings, shared libraries, root filesystem... To rule all
that out, first build a statically linked version of the following "hello
world" program with your cross compiler toolchain:

#include <stdio.h>

int main(int argc, char *argv)
{
  printf("Hello world!\n");
  sleep(999999999);
}

Now try to boot your device with an "init=" argument pointing to your
hello world program. Did you see the hello world message? Until you
do, don't bother messing with busybox init.




Once you've got it working statically linked, try getting it to work
dynamically linked. Then read the FAQ entry How
do I build a BusyBox-based system?
, and the
documentation for BusyBox
init
.

----------

I compiled it and placed it on the /hello_world in my newly filesystem image, rootfs.img, prepared for qemu (this position on fs is not so important, as long as you pass correct path to qemu):


qemu -hda rootfs.img -kernel bzImage -append "root=/dev/hda init=hello_world"

or

qemu -hda rootfs.img -kernel bzImage -append "root=/dev/hda init=/hello_world"


in my case would be the same thing, and it did the job. That way we can observe that root fs was correctly mounted, that init was called and executed correctly, and boot will here stuck because of sleep() call in hello_world.c

Capturing output of qemu

In order to capture output of qemu, it is needed to issue command like this:

qemu -hda rootfs.img -kernel bzImage -append "root=/dev/hda console=ttyS0" -serial stdio

This way boot messages will be redirected to host vga console, and can be copy/pasted fot googleing and debugging.

For thia to work, virtual console in kernel must be enebled (which by default is the case). Look under device drivers -> charcter devices -> virtual terminal, or grep .config for CONSOLE.

One more note, from Remote Serial Console HOWTO:

----------------------------

The Linux kernel is
configured to select the console by passing it the
console parameter. The
console parameter can be given repeatedly, but
the parameter can only be given once for each console technology.
So console=tty0 console=lp0 console=ttyS0 is
acceptable but console=ttyS0 console=ttyS1 will
not work.

When multiple consoles are listed output is sent to all
consoles and input is taken from the last listed console. The last
console is the one Linux uses as the /dev/console device.

The syntax of the console parameter is
given in Figure 5-1.


Thursday, November 20, 2008

Problems with booting vanilla image in qemu

I built vanilla bzImage with intention to run it in qemu, using command:

qemu -hda rootfs.img -kernel bzImage -append "root=/dev/hda"

instead of previous:

qemu -hda rootfs.img -kernel vmlinuz-2.6.18-4-k7 -initrd initrd.img-2.6.18-4-k7 -append "root=/dev/hda"

where
I used prebuild Debian kernel (ths already patched), provided as a
binary with the distro. Note here that initrd image is provided also
and had to be used with the Debian kernel which I wanted to avoid (by
building my own vanilla).

rootfs.img I used was created using Busybox:

  1. make menuconfig
  2. make
  3. make install
Find the files under busybox/_install:

drasko@Lenin:~/lddTutorial$ ls busybox-1.12.1
applets debianutils LICENSE runit
arch docs loginutils scripts
archival e2fsprogs Makefile selinux
AUTHORS editors Makefile.custom shell
busybox examples Makefile.flags sysklogd
busybox.links findutils Makefile.help testsuite
busybox_unstripped include miscutils TODO
busybox_unstripped.map init modutils TODO_config_nommu
busybox_unstripped.out _install networking util-linux
Config.in INSTALL printutils
console-tools libbb procps
coreutils libpwdgrp README


drasko@Lenin:~/lddTutorial$ ls busybox-1.12.1/_install/
bin linuxrc sbin usr



After that, rsync _install from busybox with rootfs.img file, formated to ext2:


  1. dd if=/dev/zero of=rootfs.img bs=10000k count=1
  2. mkfs.ext2 -F rootfs.img
  3. mkdir /mnt/rootfs
  4. mount -o loop rootfs.img /mnt/rootfs
  5. rsync -a busybox/_install/ /mnt/rootfs/
  6. chown -R root:root /mnt/rootfs/
  7. sync

Cool, now we have root FS on our file. We can now boot with:



qemu -hda rootfs.img -kernel bzImage -append "root=/dev/hda"



So, I built vanilla kernel bzImage, but wanted minimal size - i started with:

make allnoconfig

and turn on one by one.



First error - I missed support for IDE drive - device drivers not
selected in make menuconfig prevented the kernel to recognize /dev/hda
given to qemu as a hard disk partition. It gave kernel panic something
like:

Undefined block(0,0).



Back to the make menuconfig, turn on block devices, and under Device Drivers find IDE sections. Make.



That worked, but here comes new kernel panic:
Kernel panic - not syncing: No init found. Try passing init= option to kernel.

Obviously, there is init missing, and that is most because there is no console on the newly created rootfs.img.

The
thing is that /dev directory is dynamically created by kernel, but
kernel has no means in creating console. It has to be created manually.

Well,
why did not previous run complained, the one with Debian kernel?
Because of initrd. This image has udev, which can dynamically make
console using hotplug, when enabled in kernel (which probably is the
case of Debian pre-build kernel).

---
As a digression:

Following the Debian Kernel Handbook, initrd.img can be unpacked:


$ zcat /boot/initrd.img-2.6.18-4-k7 | cpio -i


After unpacking we can inspect contents of initrd directory:

drasko@Lenin:~/dmel/initrd$ pwd
/home/drasko/dmel/initrd

drasko@Lenin:~/dmel/initrd$ ls
bin conf etc init initrd.img-2.6.18-4-k7 lib sbin scripts

drasko@Lenin:~/dmel/initrd$ ls sbin/
depmod modprobe rmmod udevd udevsettle udevtrigger


---

In our vanilla kernel we do not have initrd, we tried to skip this step
by simplifying kernal and static build of all needed stuff.

That's why we have to create /dev/console manually in our filesystem (rootfs.img).

Creating device files when programs complain:
  1. mkdir /mnt/rootfs/dev
  2. mknod /mnt/rootfs/dev/console c 5 1
  3. mknod /mnt/rootfs/dev/null c 1 3
Taking the GNU/Linux host as an example to find correct
major and minor numbers:
ls -l /dev/console
ls -l /dev/null


-----------------------

Final note: Trying with kernel 2.6.27, I saw that init is working correctly, even for the minimal configuration. So - avoid 2.6.23 - it is buggy. Not only that it can not be build with gcc-4.3, but also loop.o gives compilation error whenn loop block device support is selected in kernel. And, yes, init is dead...

-----------------------

Select text from qemu

I found it difficult to copy/paste boot messages from qemu. THat is because qemu is using SDL for display.

I tried adding "console=/dev/ttyS0" in the -append section, which should output messages from the guest kernel though serial connection onto the host console. For working (Debian) kernel, this starts booting in quemu window, but whe a kernel is uncompressed, then starts writing on the host console the rest of the boot process. If -nographic switch to qemu is added, than it will not even start booting in separate window, but go to the console right away. The -nographic switch actually gives -serial stdio switch internaly to qemu in ordet to send everything to host stdio.

 But - for my vanilla compiled kernel this does not work, it just stucks, probablybecause I did not enable this support in menuconfig.

My help was to use -curses switch, which boots qemu in ncurses environment, where we can copy/paste in the usual way.

Also, to switch to the monitor console in -curses use Alt+2, or ESC and then press 2. There you can write quit to quit qemu.
To go back to guest main console press Alt+1.

This is different from the SDL qemu environment, where you tooggle this with Ctl+Alt+1 or Ctl+Alt+2.


Sunday, November 2, 2008

Taking Notes

I found that nice ways to collect related information are:
  1. This blog
  2. Virtual notebook
For editing thia blog I use Firefox plugin (http://www.scribefire.com/).

For virtual notebook I use Google notebok, Firefox plugin (http://www.google.com/notebook/download).

Saturday, November 1, 2008

Vim as a C IDE

Ingredients:

TAGLIST
Nice plugin for jumping on tags within currently opened C module. More info on http://vim-taglist.sourceforge.net/ and http://vim.sourceforge.net/scripts/script.php?script_id=273.

Requires Exuberant CTAGS (http://ctags.sourceforge.net/).

Few nice settings in .vimrc:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" CTags
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"let Tlist_Ctags_Cmd = $VIM.'\ctags.exe' " Location of ctags
let Tlist_Sort_Type = "name" " order by
let Tlist_Use_Right_Window = 1 " split to the right side of the screen
let Tlist_Compart_Format = 1 " show small meny
let Tlist_Exist_OnlyWindow = 1 " if you are the last, kill yourself
"let Tlist_File_Fold_Auto_Close = 0 " Do not close tags for other files
"let Tlist_Enable_Fold_Column = 0 " Do not show folding tree
let Tlist_Auto_Open = 1 " Automatically open the taglist window on Vim startup
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""


NERDTree

Nice file explorer. Here is the link: http://www.vim.org/scripts/script.php?script_id=1658.
To keep it open on start of every file (* glob in the following Vim's autocomand means everyfile),
put this line in your .vimrc:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Autocommands
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
au vimenter * nerdtree " fire up NERDTree on entering vim

minibufexpl

From the site (http://www.vim.org/scripts/script.php?script_id=159): Elegant buffer explorer - takes very little screen space. This give
Vim "tabbing" for files opened from NERDExplorer on doubleclick, which will start to open in the central window, but in a different buffer. Minibufexpl gives opportunity to easy switch between the buffers.

Here is my .vimrc extract:
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Minibuf
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:miniBufExplTabWrap = 1                 " make tabs show complete (no broken on two lines)
"let g:miniBufExplModSelTarget = 1
let g:miniBufExplSplitToEdge = 0
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Buffers from MBE window are delted by pressing "d" when cursor is on the tab.

Other Utilities
Except from Exuberant CTAGS, mentioned before I recommend also:
  1. cscope (http://cscope.sourceforge.net/)
  2. Color Scheme Sampler Pack (http://www.vim.org/scripts/script.php?script_id=625)
  3. c.vim (http://www.vim.org/scripts/script.php?script_id=213)
  4. CRefVim (http://www.vim.org/scripts/script.php?script_id=614)
All are straigtforward to install. Additional notes for CRefVim:
  • copy all, ecpecially docs to .vim folder
  • run :helptags ~/.vim/doc   (or :helptags c:\vimfiles\doc for Windows)
  • \cr normal mode:  get help for word under cursor


Code Syntax Highlighting on Blogger

Here is what I found here and especially here:

Syntaxhighlighter is a cool JS library for syntax highlighting on a web page.
  1. Download the latest version
  2. Unrar to a temp folder. ex: c:\temp\syntaxhighlighter
  3. Transfer the folders (Scripts and Styles) to a web server. I used googlepages to host my files (just use menu on the right side to upload all the files. Remeber, not all shBrush.js have to be uploaded, but only the ones you will use).
  4. Open blogger.com and sign in.
  5. Goto "Template" and choose "Classic" layout. (This is not needed with new wersion of Syntaxhighlighter. To do this anyway go to the EditHTML, and then in the left bottom of the page under HTML editing window find a link "Revert to the classic template" - of course, supposed that you have been using some more advanced template and not the classic one)
  6. Goto Edit Html.
  7. Right after <head> html tag of the template code insert the something like:
<link href="http://drasko.draskovic.googlepages.com/SyntaxHighlighter.css" type="text/css" rel="stylesheet" />
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shCore.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushCpp.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushPhp.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushPython.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushVb.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushJava.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushCSharp.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushRuby.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushXml.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushCss.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushJScript.js"></script>
<script language="javascript" src="http://drasko.draskovic.googlepages.com/shBrushSql.js"></script><p></p>p>
Do not forget to change lines like http://drasko.draskovic.googlepages.com/shCore.js
to
http://youraccount.googlepages.com/shCore.jsGood.

One more step left - just before the closing tag insert:

<script language='javascript'> dp.SyntaxHighlighter.ClipboardSwf = 'http://drasko.draskovic.googlepages.com/clipboard.swf';
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
</script>
Good. Now you are ready to use it - just embrace your code with <pre> xml tags, like here:

<pre name="code" class="java">
...some code in here...
</pre>