Plan9 Kernel Booting on OLPC (2007/08/19)

Finally we have Plan9 kernel up and running on OLPC ! Here is the screen shot



Fixing OLPC Crash Problem (2007/08/16)

Today I fixed OLPC crash problem. Problem is with lowraminit() function in memory.c Plan9 reads BIOS data area to figure out free memory below 640 K. But since OLPC doesn’t have a PC BIOS, I have modified the OLPC loader to write to BIOS data area that 639 KB is free.

Also I have updated x86amd table in devarch.c I have added Geode-LX processor entry to this table. So that Plan9 will be able to detect Geode processor correctly.

Automated boot script for Plan9 Kernel (2007/08/16)

I have created a small forth boot script to automate booting of plan9 kernel on OLPC. You need to create /boot directory on USB thumb drive and copy olpc.fth to /boot.

Once open firmware sees disk:/boot/olpc.fth file it will execute this script as part of its automated boot sequence.

OLPC plan9 kernel Changes (2007/08/14)

Following files are added to /sys/src/9/pc/ which add EGA emulation on top of OLPC linear frame buffer.

font_sun12x22.h
lfbgeometry.h
lfbega.c
olpc-egainit.c
olpc-egalib.c
olpc-ega.h

Following files are modified :

l.s - Here we need to make a new 4 MB page table entry for mapping OLPC’s linear framebuffer. Also instead of calling main, olpc_display_init is called which prints Plan9 on screen using EGA emulation code. After that HLT is called so that machine won’t reboot.

mkfile - Added entries for new EGA code.

Booting plan9 on OLPC (2007/08/10)

Finally Plan9 kernel is up and running on OLPC !!

Here is the complete procedure to boot plan9 on OLPC:

  1. You will need a USB thumb drive and OLPC laptop (of course).

  2. Following 3 files are needs, which should be stored on USB drive.

    1. plan9.ini : plan9 configuration file
    2. 9pcf : plan9 kernel
    3. loader.elf : Bootloader which loads plan9 kernerl (9pcf) on OLPC
  3. When you start the OLPC laptop, you need to interrupt the boot sequence to go to open firmware (OFW) command prompt. Here is the procedure:

    1. Hold down the Game key when machine starts.
    2. When asked (on screen) release the game key, after releasing it, OFW will start probing for hardware.
    3. After finishing the probing, OFW will ask you to press Esc key within 3 seconds. Once you press Esc then you will land up to OFW command prompt.
  4. To check files on attached thumb drive execute following command,
    dir disk:\

  5. Execute following command to boot loader.elf instead of standard linux kernel.
    setenv boot-device disk:\loader.elf

  6. Execute following command to keep USB system alive after OFW transfers control to plan9 boot loader.
    ' noop to go-hook

  7. Execute following command to map OLPC’s linear frame buffer to virtual address 0xfd000000.
    h# 910 config-l@ dup 100.0000 -1 mmu-map

  8. Finally, we are ready to boot plan9. Here is the final command,
    boot

And you should see Plan9 printed on screen !!
Currently it only prints plan9, as there is no proper display driver.

Plan9 kernel image format (2007/08/07)

Today I decided to leave plan9 ELF booting effort. Plan9 linker’s ELF output is not correct. This is creating lot of problems.

So now I am going to write custom boot loader for plan9’s kernel.

First thing i need to do is to understand plan9 kernel’s format.

Here is the information that i got from a.out.h:

struct  Exec
{
    long    magic;          /* magic number */
    long    text;           /* size of text segment */
    long    data;           /* size of initialized data */
    long    bss;            /* size of uninitialized data */
    long    syms;           /* size of symbol table */
    long    entry;          /* entry point */
    long    spsz;           /* size of pc/sp offset table */
    long    pcsz;           /* size of pc/line number table */
};

I wrote a simple C program to read plan9 kernel image and print above information from it.

Kernel file image size = text + data + syms + spsz + pcsz

Also another important thing that I found out is that, this header is in big endian format, so on x86 architecture we need to swap data to read it correctly.

Mmu setup problem for kernel startup (2007/08/07)

By default plan9 kernel’s text section starts at 0xF0100020 which is around virtual address 3841 MB. 9load loads kernel at physical address 0x100020, and then kernel sets up correct memory mappings using paging.

For OLPC we are using ELF format. OLPC’s open firmware determines start address of ELF’s txt section from ELF header. If we compile kernel in ELF format and ask linker to link its txt section at 0xF0100020 address, then OFW gives page fault, since this address is not present physically and its not mapped in current page tables.

I am linking ELF kernel at physical address 0x100020. So its loaded correctly by OFW loader. But once control is transferred to plan9 kernel, kernel code expects all address above 0xF0100020. So this is the main problem which needs to be solved.

9load page table setup (2007/08/02)

Today i read the code in 9load’s l.s file. I wanted to get information about the way 9load sets up paging for plan9 kernel.

I figured out that 9load turns on paging. It identity maps first 16 MB of memory to 2 GB and above it.

I find this quite odd, normally bootloader never uses paging, when kernel gets control it sets up the page tables.

Now my next task is to check the startup code in kernel, and figure out how it uses this mapping, and if possible remove dependency from 9loads memory mapping.

B4 Laptop Arrived (2007/07/18)

Today I got the B4 laptop. Its very fast compared to previous B1 machine. OLPC is making impressive progress.

I also completed reading about paging and plan9 compiler and assembler papers.

Things to do next (2007/07/12)

I found out that plan9 kernel startup point is in l.s file.
9load enables paging and maps first 16 MB of RAM identity mapped.
OFW doesn’t support this. Also plan9 assembly is somewhat different than GNU or Intel assembly. Looking at this issue I think I need to read following things first before proceeding further:

  1. Paging - Page Tables Setup etc.
  2. How to use Plan9 C compiler - Rob Pike
  3. A Manual for Plan9 assembler - Rob Pike

Open Firmware Client Interface Information (2007/07/12)

While handling control to Operating System; OFW passes address of client interface handler in register EAX. So in Plan9 kernel we need to copy this value from EAX and store it in a variable. And we need to do this before somebody else overwrites EAX register.

Rules for making OFW client interface call from Operating System:

  1. CS nad DS selectors should point to flat 4GB segments.
  2. EAX should contain pointer to argument array.
  3. On return from OFW, EAX contains return value.

First OLPC Program (2007/07/10)

To check whether a program compiled using Plan9’s compiler works on OLPC I wrote following program. This program fills OLPC’s screen with Blue color.

void
_main(void)
{
    int i=0;
    unsigned short *fb = (unsigned short *) 0xfd000000;
    for(i=0; i<1200*900;i++)
    {
        *fb = 0x0015U
        fb++;
    }
}

Here linear frame buffer start address is 0xfd000000.
OLPC Screen Resolution is 1200x900.
Color Depth is 16 bits.
0x0015U is value for Blue color.

I compiled this program using following commands,

8c color.c
8l -H5 -T0x100000 color.8

I got 8.out which was in ELF format. I wanted OLPC’s open firmware to load this executable at 1MB so I gave -T0x100000 option to 8l.

To execute this program, copy it to USB disk. Attached this USB disk to OLPC and boot the laptop. You need to press ‘x’ key in game pad to interrupt the booting sequence. After this you need to press Esc key to enter to open firmware boot prompt. Once you are at open firmware boot prompt execute following command to check whether USB disk is detected properly and appropriate FS driver is loaded.

dir disk:\

This command should print out contents of USB disk’s root directory.

Now you need to tell open firmware (OFW) that you want to load 8.out from USB disk and execute it. Execute following command,

setenv boot-device disk:\8.out

OFW by default resets USB system just before handling over control to new kernel. If you need to turn off that behaviour then you should execute following command,

' noop to go-hook

Now we need to tell OFW to map linear frame buffer video memory to 0xfd000000 address. Execute following command,

h# 910 config-l@ dup 100.0000 -1 mmu-map

After this you can boot 8.out by executing command,

boot

Some other useful OFW commands,

reset-all = To reset all hardware and reboot
power-off = Shutdown
print-env = Prints all the Environment
dev / = Sets to root of device tree, after this you can use ls command to print the tree.
.properties = Prints properties of the selected node.

Plan9 Tips (2007/07/10)

I want to documents some tips here, which are quite useful.

Copying files from Plan9 to Linux using floppy:

Create a 1.44 MB floppy image in linux, format it with FAT FS. Use it as 1st floppy disk in qemu.
In Plan9, use following commands to access it:
a:
cd /n/a:

Editing plan9.ini configuration file:

Type following command in Plan9,
9fat:
cd /n/9fat

Command to reboot / halt the system: reboot fshalt

For PC 386:
8c - is the C compiler
8a - is the assembler
8l - is the linker

One typically needs to add u.h and libc.h files as headers for C programs.

Important linker options for 8l are:
-H5 = Output is generated with ELF header
-l = Suppress default loading of startup files.
-T0x100000 = Loads Text section at 1MB

Default Entry symbol is _main

Default Plan9 kernel configuration for PC is pcf

Procedure for Compiling kernel:
cd /sys/src/9/pc
mk 'CONF=pcf'

To compile kernel in ELF format I modified /sys/src/9/pc/mkfile and added -H5 option to $(LD) command.

Hello (2007/07/08)

This my first post !

Hello World !!!

Making progress (2007/05/30)

Have made some progress with the gsoc.cat-v.org site and setup, a handful of brave souls have got accounts already, and i hope that most of the work left is to add some real content (I hope others will help out with that ;))

While fixing a bug in the blog code (all six lines of it), I found a neat trick: Given a list of paths, how to list the full paths of all files in those dirs ordered by file name:

; l = ( /foo /bar/baz/bax /) 
; ls $l^'/./' | sort -t. +1

Enough for today, when I wake up I should announce the site to the gsoc list and try to setup an irc meeting for tomorrow so we can get things going. Thanks to everyone that helped debug and test things.

Hi there (2007/05/28)

Hullo! ^_^