Friday, January 27, 2012

Thin client IBM NetVista N2200 Model 8363 kernel compile for NFS root




IMPORTANT NOTE: This blog contains several pages related to Linux on the IBM NetVista N2200 (Model 8363). All the information is summarized here:

Linux on the IBM NetVista N2200 (Model 8363) page on Smithfarm - the Brain


Currently on my IBM NetVista N2200, I am booting Linux kernel verion 2.6.31 to a root filesystem exported from a server over NFS ("Root-NFS" for short). Due to the quirky nature of the N2200 hardware and firmware, this was not simple to accomplish.

There are two ways that I know of to do Root-NFS on the N2200: first, you can hard-code the required kernel parameters into the kernel, and second, you can include an initrd inside the kernel. Of these two, the first is much simpler.

When I got started with this Root-NFS project, I first tried to use the 2.6.18 kernel from the PusPus "distribution". After hours of trials, I gave up on getting it to do Root-NFS. To be frank, I was pretty desperate at that point. Then, a kind soul sent me an email with a kernel containing an integral initrd that worked. So, I knew it was possible and that inspired me to run further trials.

Based on work by chris007, I already had a 2.6.31 kernel compiled and running on the N2200. Soon, I found that I could hard-code the Root-NFS kernel command line parameters into that kernel and, unlike with 2.6.18, it worked!

So, why not try an even more recent kernel? Here we go:

Procedure

  • Get vanilla 3.1.10 kernel from http://kernel.org/pub/
  • Unpack it in /usr/src/linux-3.1.10
  • Create standard symlink: "cd /usr/src && ln -si linux-3.1.10 linux"
  • Patch the kernel:

1st patch:


This patch is critical - without it, the kernel will not boot. Comment out the following while loop:
arch/x86/kernel/rtc.c:
/*
* If UIP is clear, then we have >= 244 microseconds before
* RTC registers will be updated.  Spec sheet says that this
* is the reliable way to read RTC - registers. If UIP is set
* then the register access might be invalid.
*/
while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
cpu_relax();

2nd patch:


This one is not critical, but it corrects a usability issue.
    Edit drivers/video/geode/gx1fb_core.c
    
    Look for and change
     static char mode_option[32] = "640x480-16@60";
    to
     static char mode_option[32] = "1024x768-16@60";

    3rd patch:


    This patch is not useful for Root-NFS, but it's a quick-and-dirty way to have your root filesystem on the CF card. Another option would be to pass a hard-coded kernel command-line parameter (see below).
    arch/x86/kernel/setup.c
    
    replace
    ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
    
    by
    
    ROOT_DEV = Root_SDA1;
    Antonio Martins' patch-kernel script - a very nice helper. Here's the entire script:
    #!/usr/bin/perl
    
    # This script patches the ELF program-header-count in a compiled Linux Kernel.
    # This is needed to enable the kernel to run under IBM Netvista 2200 (8363).
    #
    # You need Perl to run this.
    # usage: ./patch-kernel vmlinux
    #
    # Antonio Cardoso Martins (digiplan.pt@gmail.com)
    #
    # Version 2008090701
    #
    
    # use strict;
    # use warnings;
    
    open (FH, "+<$ARGV[0]") or die "Couldn't open $ARGV[0] file for writing: $!";
    binmode (FH);
    
    seek(FH, 0x2c, 0) or die "Died seeking: $!";
    read(FH, my $value, 1) == 1 or die "died reading: $!";
    print "ELF program-header-count (offset 0x2c) of $ARGV[0]\n";
    print "Before patching was: " . unpack('C', $value) . "\n";
    
    seek(FH, -1, 1) or die "Died seeking: $!";
    print FH pack('C', 1);
    print "The value now is:    1\n";
    
    close FH or die "Died closing: $!"; 
    The resulting file is your new kernel.

    • try booting the N2200 with the new kernel


    Result: The kernel boots fine. If I use /bin/sh instead of /sbin/init, it works fine. But if I let it boot into the full Debian system, it segfaults as soon as I run bash. Here's the exact (more-or-less) error message:
    -bash: /usr/bin/id: cannot execute binary file
    Inconsistency detected by ld.so: dl-fini.c: 197: _dl_fini: Assertion `ns != 0 || i == nloaded' failed!
    bash[1388]: segfault at 4 ip . . . etc. etc.
    -bash: [: : integer expression expected

    1 comment:

    1. Hello, thanks also to your inspiration, i was able to build a complete Debian Wheezy system for Netvista N2200 with kernel 3.1.10. I will post the information on how to do it.

      ReplyDelete