Sunday 28 June 2015

On creating

I have been asked many times and for that manner many of you might have faced this before these questions "why do you do things from scratch." "Why bother when it is already done." "You should do things which are more abstract if the base is already done."

The problem with this is if a person has the qualities of questioning, reasoning and a childlike curiosity it becomes extremely hard to explain why they do it. For me it is the sense of satisfaction and happiness that I get when I understand what is it that made it work or the core principles behind it. There is also the feeling of guilt that I am not sure what I am standing on.

You get a sense of power knowing the finer details and the core principles behind it. You will be able to appreciate the cleverness of how and why it was done. You get more ideas of how it could be done. One of the pleasures that I have is re-deriving basic mathematics principles, things which I had skipped knowing that it holds true. You feel like you are in that mathematician's shoes in an adventure to prove that proof or derive that equation.

I will end this with a beautiful quote of my favorite physicist Dr.Richard Feynman which was scribbled on his blackboard at Caltech.

What I cannot create, I do not understand.
Know how to solve every problem that has been solved.


Wednesday 3 June 2015

Baremetal OS development

A year ago I had decided that I wanted to try writing a simple OS for my MINI2440 development board. The motivation was that this machine being quite powerful why waste cycles on running a full fledged OS like Linux.

Also I wanted to know how far I can go trying to bring an ARM machine to life with just my baremetal code. Being so close to the metal had always fascinated me. I had written code for micro-controllers such as the MSP430 and the STM32F103ZE and had some experience in bringing up an MCU but never brought up an entire SoC.

So the baremetal OS was born. I named it MDK (microcontroller development Kit) for developers and a kernel the MDK-OS. The idea was to have a development kit for the developers and also to have a small kernel.

This brought me to my first commit here:

https://github.com/mindentropy/s3c2440-mdk/commit/c4a9f316b4c8fd6f7984a1209b5cc473fdd3d13e


Ah the joy of seeing the LED's blink. The initial commit featured a Makefile, a linker script an assembly file for the intial interrupt vector table and the main 'C' file which contained the code to blink the LED.

What a joy it was to watch this simple code run.

In this blog I will be explaining and writing my experiences in writing the OS and the development kit. Hope this will act as a learning kit for people who want to write their own OS.


Writing is nature’s way of showing us how sloppy our thinking is.


How to setup Linux on a MINI2440 development board

Assuming an ubuntu setup and with Pengutronix Linux kernel patches for the mini2440.

RootFS creation using debian multistrap. See simple_config to create a simple 
multistrap configuration. 
 
Use tar with the following options --> -cpjvf --numeric-owner
-c --> Create
-p --> Preserve permissions
-j --> bz2.
-v --> verbose
-f --> use file archive ie. the name of the file.


tar -cpjvf <filename.tar.bz2> . --numeric-owner

Extraction is the same. Make sure you are using sudo as the file permissions usually 
will have root user permissions and the permissions are preserved.

Creation of a Emdebian rootfs.
1
2
3
4
sudo debootstrap --foreign --arch armel <debian_release_codename> <rootfs_directory> http://ftp.debian.org/debian/ Do -> cp /usr/bin/qemu-static-arm <rootfs_directory>/usr/bin
Get a root environment. Do -> sudo -i
To do a second stage install. Do -> LC_ALL=C LANGUAGE=C LANG=C chroot debian_armel_wheezy /debootstrap/debootstrap --second-stage
To trigger post install scripts. Do -> LC_ALL=C LANGUAGE=C LANG=C chroot emdebian_rootfs_wheezy_test dpkg --configure -a
 

 
Reference http://wiki.debian.org/EmDebian/CrossDebootstrap#QEMU.2Fdebootstrap_approach

Copy fstab,udev.conf,udev.rules,ts.conf files from pengutronix to the rootfs sdcard.

Reference inittab
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
id:5:initdefault:

T1::sysinit:/bin/mount -t proc proc /proc
T2::sysinit:/bin/mount -o remount,rw /
T3::sysinit:/bin/mkdir -p /dev/pts
T4::sysinit:/bin/hostname -F /etc/hostname

T5::sysinit:/etc/init.d/rcS
T6::sysinit:/bin/mount -a
#T7::sysinit:/bin/mount -t sysfs sys /sys

T0::respawn:/sbin/getty -L ttySAC0 38400 vt100







Reference passwd

1
2
3
root::0:0:root:/root:/bin/sh
bin:x:1:1:bin:/dev/null:/bin/false
nobody:x:99:99:Unprivileged user:/dev/null:/bin/false



Reference group
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
root:x:0
bin:x:1
nogroup:x:99
floppy:x:1000:
cdrom:x:1001:
tape:x:1002:
lp:x:1003:
tty:x:1004:
video:x:1005:
kmem:x:1006:
audio:x:1007:
disk:x:1008:
dialout:x:1009:
crontab:x:1010:




Reference fstab
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# UNCONFIGURED FSTAB FOR BASE SYSTEM

devpts /dev/pts devpts defaults  0 0
none /tmp   tmpfs defaults,mode=1777,uid=0,gid=0 0 0
none /sys   sysfs defaults   0 0
debugfs /sys/kernel/debug debugfs defaults   0 0
usbfs /proc/bus/usb  usbfs devgid=14,devmode=0660  0 0

none /var/log  tmpfs defaults,mode=0755,uid=0,gid=0 0 0
none /run  tmpfs defaults,mode=0755,uid=0,gid=0 0 0
none /run/lock  tmpfs defaults,mode=0755,uid=0,gid=0 0 0
none /var/tmp  tmpfs defaults,mode=1777,uid=0,gid=0 0 0

/etc/securetty

Add ttySAC0 entry at the end of securetty file.

Copy relevant files like udev rules from pengutronix folders.

Kernel Compilation

Get the kernel from kernel.org. If the patch from pengutronix is 3.9.1(i.e. patch.3.9.1.bz2) download the
3.9.0 kernel and the patch will patch the version to 3.9.1. Also if the patches directory shows 3.9 then 
download the 3.9.0 kernel.

Using quilt to apply the 'series' patch.

Create a sym link called patches pointing to 
../OSELAS.BSP-Pengutronix-Mini2440/configs/platform-friendlyarm-mini2440/patches/linux-3.9/ in the
linux directory.
Create a sym link called series pointing to 
../OSELAS.BSP-Pengutronix-Mini2440/configs/platform-friendlyarm-mini2440/patches/linux-3.9/series in
the linux directory.

To apply the series of patches do -> quilt push -av

Copy kernelconfig to the defconfig
Eg: 

1
cp ../OSELAS.BSP-Pengutronix-Mini2440/configs/platform-friendlyarm-mini2440/kernelconfig-3.9 arch/arm/configs/mini2440_defconfig
Kernel compilation: 

1
2
CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm make mini2440_defconfig
CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm make menuconfig
Kernel config

Device Drivers->Graphics Support->Bootup logo check.
        -> Direct Rendering Manager.
        -> Lowlevel video output switch controls.
         ->Console display driver support -> Framebuffer console support.
         Optional 
          Framebuffer console rotation.
         Mini 4x6 font. (For smaller font).

Device Drivers->Graphics Support->Support for framebuffer devices.
        -> S3C2410 LCD framebuffer support.
        -> S3C2410 lcd debug messages.

Device Drivers->Character Devices->Enable TTY.
        -> Virtual Terminal.
File Systems-> Enable ext2,ext3
Network support -> Networking support -> IP: BOOTP support.
          IP: RARP support.


1
2
3
CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm  INSTALL_MOD_PATH=/mnt/arm make 
CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm  INSTALL_MOD_PATH=/mnt/arm make uImage
CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm  INSTALL_MOD_PATH=/mnt/arm make modules_install
uboot options:
1
2
bootargs=mini2440=5tb rootfstype=ext3 root=/dev/mmcblk0p2 rw bootdelay=rootwait ip=dhcp console=tty0 --> For lcd console output.
bootargs=mini2440=5tb rootfstype=ext3 root=/dev/mmcblk0p2 rw bootdelay=rootwait ip=dhcp console=ttySAC0 --> For serial output.
Bootcmd for sdcard boot:
1
bootcmd=mmcinit ; ext2load mmc 0:1 0x31000000 uImage ; bootm 0x31000000
Bootcmd for tftpboot:
1
bootcmd=tftpboot 0x31000000 192.168.1.101:uImage ; bootm 0x31000000
nfs setup 

1
2
3
mkdir /export
mkdir /export/fs
mkdir /export/kernel
 
/etc/exports 

1
2
3
/export 192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,async)
/export/fs 192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,async,no_root_squash)
/export/kernel 192.68.1.0/24(rw,fsid=0,insecure,no_subtree_check,async)
 
Bootcmd for nfs

1
2
3
4
5
setenv bootcmd nfs 0x31000000 192.168.1.x:/nfs/rootfs/boot/uImage \; bootm
setenv bootargs console=ttySAC0,115200 root=/dev/nfs nfsroot\=192.168.1.x:/nfs/rootfs rw ip=dhcp mini2440=5tb
        |

                                                                \----> * Do not use environment variable * 
 
NFS configuration which worked:

1
/nfs/rootfs 192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,async,no_root_squash)
For ERROR cannot umount add mini2440 to /etc/hosts in your host. For earlyprintk messages. Enable in the kernel. Also put a 
'earlyprintk'(without quotes) in bootargs
 
For eg: 
1
setenv bootargs console=ttySAC0,115200 root=/dev/nfs nfsroot\=192.168.1.x:/nfs/rootfs rw ip=dhcp mini2440=5tb earlyprintk