Monthly Archives: February 2013

How I bricked my 13 days old Thinkpad

… and switched back to my 5 year old macbook!

Here a step-by-step instruction:

  • buy a Thinkpad T530 with a Quadcore CPU
  • create an EFI partition with GPT layout
  • compile a 3.8.1 kernel with EFI stub
  • add it to your EFI bootorder; that was something like:
     echo "initrd=\arch\initrd-3.8.1.img root=/dev/mapper/root cryptdevice=/dev/sda3:root:allow-discards | iconf -f ascii -t ucs2 | efibootmgr -c -l \arch\kernel-3.8.1.efi -L "Arch (3.8.1)" --append-binary-args -" 
  • reboot
  • linux kernel: an error occurred: cannot find initrd
  • reboot
  • congratulations: you’ve bricked a thinkpad

Most probably it’s an EFI bug, because:

  1. thinkpads and those samsung laptops with EFI problems both use Phoenix bios
  2. in an article (c’t 6/13) the authors described there has to be a kernel error before your machine becomes unusable
  3. Matthew Garrett (the Linux EFI god ;)) “heard a couple of indications” (https://twitter.com/mjg59/status/307262466516197376)

Why do I use wordpress.com?

There is a simple answer for that.

I would have to write a blog engine – I haven’t found a good one

  • written in perl, c or go
  • create a static blog
  • able to highlight source code
  • I would need a domain, but I don’t like whois; so there are to-domains, but they’re not cheap, especially if you don’t buy them directly at tonic
  • If I buy such a second level domain, I’d need a dns server (and a backup dns server) to fulfill the dns requests
  • bind is hard to handle, therefore I would prefer to write my own dns server; but to do so, I first need my own datastructure library

I have visualized this problem with graphviz:

blog dependecy graph

btwotch_open(struct inode *i, struct file *f)

#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <asm/uaccess.h>

// thx http://lwn.net/Kernel/LDD3/

static char* txt[] = 
        {
        "Welcome to my new blog; perhaps you have visisted my former blog at spin.de, too. This is it's successor!\n"
        "Have a lot of fun, btwotch\n",
        "http://twitter.com/btwotch\n", 
        "http://btwotch.soup.io\n", 
        "http://mister-wong.de/user/btwotch\n"
};

static dev_t d;
static struct cdev* c;

struct txt_msg
{
    size_t written;
    char *txt;
    size_t txt_len;
};

static int btwotch_open(struct inode* i, struct file* f)
{
    int minor = iminor(f->f_dentry->d_inode);
    struct txt_msg *tm = kmalloc(sizeof(struct txt_msg), GFP_KERNEL);

    tm->written = 0;
    if (minor > 4)
        minor = 0;

    tm->txt = txt[minor];
    tm->txt_len = strlen(tm->txt);

    f->private_data = tm;

    return 0;
}

static int btwotch_close(struct inode* i, struct file* f)
{
    kfree(f->private_data);

    return 0;
}

static ssize_t btwotch_read(struct file* f, char __user *user, size_t count, loff_t *offset)
{
    size_t len, leftwrite, written;
    struct txt_msg *tm = (struct txt_msg*)f->private_data;

    if (tm->txt_len == tm->written) // that's how we do EOF!
        return 0;

    leftwrite = tm->txt_len-tm->written;
    len = (count < leftwrite) ? count : leftwrite;

    written = copy_to_user(user, tm->txt+tm->written, len);
    tm->written += len-written;

    return len-written;
}


static struct file_operations fops = {
    .owner = THIS_MODULE,
    .read = btwotch_read,
    .open = btwotch_open,
    .release = btwotch_close
};

static void register_driver(void)
{
    c = cdev_alloc();

    cdev_init(c, &fops);
    
    alloc_chrdev_region(&d, 0, 5, "btwotch-drv");

    cdev_add(c, d, 1);
    cdev_add(c, d, 2);
    cdev_add(c, d, 3);
    cdev_add(c, d, 4);

    printk("btwotch-mod: major: %d minor: %d\n", MAJOR(d), MINOR(d));

}

static void unregister_driver(void)
{
    cdev_del(c);

    unregister_chrdev_region(d, 5);

}

static int __init init_btwotch(void)
{
    register_driver();

    return 0;
}

static void __exit cleanup_btwotch(void)
{
    unregister_driver();
}

module_init(init_btwotch);
module_exit(cleanup_btwotch);

MODULE_AUTHOR("btwotch");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("the btwotch virtual device");
MODULE_SUPPORTED_DEVICE("none");