FreeBSD @ Lenovo S205 (preliminary)

The choice: Lenovo Ideapad S205

After I purchased (on my own budget) a Apple Macbook Pro -- and realizing it has as (tailored) Broadcom WiFi card -- and after my failures to replace the Mini PCI Broadcom WiFi card in my HP notebook (running Ubuntu) and thought it ought to be smart to buy a notebook with an Atheros WiFi NIC to be used for my WiFi classes.

Beeing a fan of AMD CPUs my eyes felt on Lenovo's AMD Vision notebook. It is a low-end consumer notebook/netbook without an optical drive, but it's specs promised has some advantages:

My ideas were, to use the notebook mainly for WiFi sniffing in my course -- and Atheros is known to be the best choice for this operation; including WiFi penetration and hacking.
This notebook it is reasonable light-weight and has a good battery life time -- to use it as a portable node -- with enough CPU power, I thought: This is my choice.
Conrad's choice I went for the next the model with 4 GByte of memory while considering to replace the standard drive with a SSD.
However, this choice was accompanied with the Microsoft 'Seven' OS to be installed (well, I considered it as challenge; not as usable option.

The challenge: Memory upgrade and SSD drive

Since the Lenovo S205 is a consumer type of hardware, any upgrade is not that easy; however some helpful video clips exist, relaxing the situation: Upgrading S205 (in German) Thus, I purchased in addition a Crucial M4-CT128M4SSD2 drive with 128 GByte capacity -- enough to run a current Unix OS and perhaps to store my lessons + some source code.

By means of some decent and fitting screw drivers the upgrade worked well. Disassembling and reassembling the case with some caution is not a big deal.

First woes: Windows installation

My Lenovo came with a Microsoft 7 Home Premium edition installed -- and a lot of Lenovo tools in addition. Since our university is participating in the academic ELMS program, I went to re-install Window 7 Professional edition on that notebook. This turned out to require at least 12 hours of my lifetime:

Once Windows 7 was installed on the original disk drive (350 GByte), I replaced it with the 128 GByte SSD and the Windows disk went into my drawer.

The surprise: Windows boot manager

One very stupid decision Lenovo's engineers did, was to place the multiboot function key to F12. Why is this a bad choice ? Because there is no F12 key on the keyboard! Rather, it requires to simultanuously press Fn + F11 (needing two hands). Live could be so simple ...

Entering the boot menu, shows up onther surprise: The Windows Boot Manager. The order in the boot menu can be customized by means of the standard BIOS setup accessible thru F2. However, there is no explanation -- neither in the BIOS itself, nor on any resource I was able to 'google' for, telling the meaning of this entry.

WindowsBootManager

Lenovo's boot manager -- available by means of Fn+F11 shows here the (customizable) entries of my SSD hard disk, the PXE boot option and the 'Windows Boot Manager'

Hugh? Never heard of a Windows Boot Manager. From my Windows experience I just knew boot.ini !

The discovery: The Windows partition layout

My Windows installation I kept on my original disk (altough have wiped out the Lenovo's OEM Windows) showed the following setup, attaching the disk setup after having booted FreeBSD from an USB stick:
WindowsDiskPartitioning

Windows default disk partitioning after a standard 'Seven' intallation.

As far, as I have found out, Microsoft uses the following disk layout:

  1. Due to a bug in Windows XP, any Microsoft bootable sectore (apart from the leagcy MBR itself), needs to be positioned at sector 2048, leaving the first sectors wasted.
  2. The EFI partitioned carries the Windows boot manager.
  3. The Microsoft resevered partition can be used to install as recovery Operating System.
  4. The actual Microsoft NFTS partition simply called the Basic data partition

The Lenovo S205 provides an additional button, in order to invoke the Microsoft reserved partition. It is this one:

WindowsReinstallButton

Pressing this magical button (red arrow) reinstalls Windows from the reserved GPT partition.

The exploration: EFI Bios

Lenovo's S205 technical description is at best 'brief', It does not tell anything about the BIOS; or whether it is a standard BIOS at all or perhaps the EFI (Extensibal Firmware Interface); mayby one might estimate this from the size of the PROMs. Apart from the EFI Wikepedia page, a pesentation from Matthew Garrett at the LinuxConf 2012 in Australia provides some interesting insides into the scope and the origin of the EFI Bios: Developed by Microsoft for their IA64 architecture, EFI probably it's long lasting (and presumable buggy) heritage. The amount of code comes closes to the size of the FreeBSD kernel while it provides in essence -- apart from device initialisation -- a direct FAT support.

EFI system initialisation

Screen shot of Matthew's LinuxConf 2012 talk explaining the EFI system initialisation.

And this is the magic: The Lenovo's Bios labels and accesses the EFI system partion as 'Windows Boot Manager' under two conditions:

  1. The EFI partition starts at sector 2048.
  2. The EFI partition is FAT formated.
This 'partiton alignment' is very crucial for windows, as explaind by Thromas Kern's Wiki (German). By now, we should have learnded, that the Lenovo S205 is pretty much tailored for Microsoft's OS.

The struggle: Installing FreeBSD 9

I got FreeBSD 9 RC1 on memory stick working for the Lenovo S205. Unlike it's predecessor FreeBSD 8.2, it recognizes the Atheros 9285 WiFi and the Realtek RTL 8201E Ethernet NIC (using the rlphy module).

Now, the basic question is, how to set up the system. Since -- regarding file systems -- I'm a bit conservative (in Feb 2012 my colleage Peer Heinlein mentioned to be very disappointed by EXT4's performance on the SAGE mailing list) thus, I only took UFS (+ journaling) into account, leaving ZFS and perhaps encryption aside.

The experience: GPT partitioning on the Lenovo S205 for FreeBSD

Since I purchased the Lenovo s205 with the intention in mind to learn more about the GPT partitioning scheme, of course a searched the web for some decent information. The ones I got:

The first trial: GPT partitioning the Lenovo S205 for FreeBSD with sysinstall

The first guess would be to simply let sysinstall doing the dirty business the partition the disk, after booting from the USB stick with FreeBSD 9. It all looked promising. Having installed dozends of FreeBSD systems, this is usually a snap. Well -- not for the Lenovo S205. Even after the install process finished with a promising 'reboot' advice, the only thing I got after rebooting was the PXE boot screen. Whether I chose ATA HDD0: MD4 ... or Windows Boot Manager; there was no sign of F1: FreeBSD ... Something definitevely went very wrong.

The theory: GUID partitioning and disk layout

Ok, I thought, it is time to dive deeper into the the GPT disk layout and mechanisms togther with the EFI BIOS Linus Torvalds considering as brain damaged.

GUID: Generic UIDs

Every GPT partition is identified by a Generic UID GUID. The GUID on the one side, posseses a significat entropy and a significant name space; on the onther hand are hierarchial structured and a particular scheme or individual partition type needs to be requested (by the respective name space owner/authority) and allocated.

As we have ssen, in addition with the (raw) GUID partition number, we can diplay the assigned partion name and the label by means of FreeBSD's gpart options -r (raw), -p (provider, default), -l (labels). As we can see, these information might not to be consistent:

WindowGPTInformation

Viewing the Window's GPT information with different gpart options

WindowGPTInformation

GPT partitioning scheme layout according to Wikipedia

The second trial: FreeBSD GPT partitioning with gpart

During my trials with the GPT partitioning I became more and more familiar with FreeBSD's gpart. After the (quite a lot of) failures, I was loooking for some alternatives, since I had the suspicion, that the gpart tool might be buggy. Thus, I checked for with one eye the MacOS Disk manager utility and with the other eye Linux gpt utiility which comes with on an ISO-Linux boot image.

Lessons learned: The failed attempts not only proofed that any GPT tools are particular customized and restricted to their respective task, but in addition significantly raised my trust in FreeBSD's gpart which seems to be the most univeral and mature tool. This is understandable in particular with respect to Linux, since those folks joined the GPT train relatively late.

However, there is one additonal lesson which needs to be mentioned: Don't mix gpart'ting a disk with legacy tools, like fdisk. We come to that point later.

On the bottom line, gart'ing a disk is simple. Actually, it is even much simpler. But this is another item to be uncovered.

The standard way to set up GPT disks, can be found in b0rken's advice.

Step 1: Boot from USB stick. You could use the DVD ISO image as well; but the Memstick image boots much faster.
Step 2: Get get full control of the partitioning process, invoke the shell after the initial boot.
Step 3: Identify your disk's device node address, while checking the dmesg output and the device node entries present at /dev/a*. In my case of the Lenovo they show up as ...

$ dmesg
Copyright (c) 1992-2012 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 9.0-RELEASE #0: Tue Jan 3 07:46:30 UTC 2012
root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
CPU: AMD E-350 Processor (1596.63-MHz K8-class CPU)
Origin = "AuthenticAMD" Id = 0x500f10 Family = 14 Model = 1 Stepping = 0
Features=0x178bfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,MMX,FXSR,SSE,SSE2,HTT>
Features2=0x802209< AMD Features=0x2e500800<SYSCALL,NX,MMX+,FFXSR,Page1GB,RDTSCP,LM>
AMD Features2=0x35ff<LAHF,CMP,SVM,ExtAPIC,CR8,ABM,SSE4A,MAS,Prefetch,IBS,SKINIT,WDT>
TSC: P-state invariant, performance statistics
real memory = 4294967296 (4096 MB)
avail memory = 3679719424 (3509 MB)
Event timer "LAPIC" quality 400
ACPI APIC Table: FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
FreeBSD/SMP: 1 package(s) x 2 core(s)
cpu0 (BSP): APIC ID: 0
cpu1 (AP): APIC ID: 1
ioapic0: Changing APIC ID to 2
MADT: Forcing active-low polarity and level trigger for SCI
ioapic0 irqs 0-23 on motherboard
kbd1 at kbdmux0
acpi0: <LENOVO CB-01> on motherboard
acpi0: Power Button (fixed)
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
acpi_timer0: <32-bit timer at 3.579545MHz> port 0x808-0x80b on acpi0
cpu0: <ACPI CPU> on acpi0
cpu1: <ACPI CPU> on acpi0
acpi_ec0: <Embedded Controller: GPE 0x3> port 0x62,0x66 on acpi0v hpet0: <High Precision Event Timer> iomem 0xfed00000-0xfed003ff on acpi0
Timecounter "HPET" frequency 14318180 Hz quality 950
Event timer "HPET" frequency 14318180 Hz quality 550
Event timer "HPET1" frequency 14318180 Hz quality 450
acpi_button0: <Power Button> on acpi0
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pcib0: Length mismatch for 3 range: 1f000000 vs 8000000
pci0: <ACPI PCI bus> on pcib0
vgapci0: <VGA-compatible display> port 0x2000-0x20ff mem 0xe0000000-0xefffffff,0xf0200000-0xf023ffff irq 18 at device 1.0 on pci0
hdac0: <ATI (Unknown) High Definition Audio Controller> mem 0xf0244000-0xf0247fff irq 19 at device 1.1 on pci0
ahci0: <ATI IXP700 AHCI SATA controller> port 0x2118-0x211f,0x2124-0x2127,0x2110-0x2117,0x2120-0x2123,0x2100-0x210f mem 0xf024a000-0xf024a3ff irq 19 at device 17.0 on pci0
ahci0: AHCI v1.20 with 1 3Gbps ports, Port Multiplier supported
ahcich0: <AHCI channel> at channel 0 on ahci0v ohci0: <OHCI (generic) USB controller> mem 0xf0249000-0xf0249fff irq 18 at device 18.0 on pci0
usbus0: <OHCI (generic) USB controller> on ohci0
ehci0: <EHCI (generic) USB 2.0 controller> mem 0xf024a500-0xf024a5ff irq 17 at device 18.2 on pci0
usbus1: EHCI version 1.0
usbus1: <EHCI (generic) USB 2.0 controller> on ehci0
ohci1: <OHCI (generic) USB controller> mem 0xf0248000-0xf0248fff irq 18 at device 19.0 on pci0
usbus2: <OHCI (generic) USB controller> on ohci1
ehci1: <EHCI (generic) USB 2.0 controller> mem 0xf024a400-0xf024a4ff irq 17 at device 19.2 on pci0
usbus3: EHCI version 1.0
usbus3: <EHCI (generic) USB 2.0 controller> on ehci1
pci0: <serial bus, SMBus> at device 20.0 (no driver attached)
hdac1: <ATI SB600 High Definition Audio Controller> mem 0xf0240000-0xf0243fff irq 16 at device 20.2 on pci0
isab0: <PCI-ISA bridge> at device 20.3 on pci0
isa0: <ISA bus> on isab0
pcib1: <ACPI PCI-PCI bridge> at device 20.4 on pci0
pci1: <ACPI PCI bus> on pcib1
pcib2: <ACPI PCI-PCI bridge> irq 16 at device 21.0 on pci0
pci2: <ACPI PCI bus> on pcib2
re0: <RealTek 810xE PCIe 10/100baseTX> port 0x1000-0x10ff mem 0xf0004000-0xf0004fff,0xf0000000-0xf0003fff irq 16 at device 0.0 on pci2
re0: Using 1 MSI-X message
re0: turning off MSI enable bit.
re0: Chip rev. 0x40800000
re0: MAC rev. 0x00000000
miibus0: <MII bus> on re0
rlphy0: <RTL8201E 10/100 media interface> PHY 1 on miibus0
rlphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto, auto-flow
re0: Ethernet address: f0:de:f1:61:d4:6b
pcib3: <ACPI PCI-PCI bridge> irq 16 at device 21.2 on pci0
pci3: <ACPI PCI bus> on pcib3
ath0: <Atheros 9285> mem 0xf0100000-0xf010ffff irq 18 at device 0.0 on pci3
[ath] AR9285E_20 detected; using XE TX gain tables
ath0: AR9285 mac 192.2 RF5133 phy 14.0
acpi_lid0: <Control Method Lid Switch> on acpi0
acpi_button1: <Sleep Button> on acpi0
acpi_tz0: <Thermal Zone> on acpi0
acpi_tz1: <Thermal Zone> on acpi0
atrtc0: <AT realtime clock> port 0x70-0x71 irq 8 on acpi0
Event timer "RTC" frequency 32768 Hz quality 0
attimer0: <AT timer> port 0x40-0x43 irq 0 on acpi0
Timecounter "i8254" frequency 1193182 Hz quality 0
Event timer "i8254" frequency 1193182 Hz quality 100
atkbdc0: <Keyboard controller (i8042)> port 0x60,0x64 irq 1 on acpi0
atkbd0: <AT Keyboard> irq 1 on atkbdc0
kbd0 at atkbd0
atkbd0: [GIANT-LOCKED]
psm0: <PS/2 Mouse> irq 12 on atkbdc0
psm0: [GIANT-LOCKED]
psm0: model Generic PS/2 mouse, device ID 0
acpi_acad0: <AC Adapter> on acpi0
battery0: <ACPI Control Method Battery> on acpi0
sc0: <System console> at flags 0x100 on isa0
sc0: VGA <16 virtual consoles, flags=0x300>
vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
ppc0: cannot reserve I/O port range
hwpstate0: <Cool`n'Quiet 2.0> on cpu0
Timecounters tick every 1.000 msec
hdac0: HDA Codec #0: ATI R6xx HDMI
pcm0: <HDA ATI R6xx HDMI PCM #0 HDMI> at cad 0 nid 1 on hdac0
hdac1: HDA Codec #0: Conexant CX20590
pcm1: <HDA Conexant CX20590 PCM #0 Analog> at cad 0 nid 1 on hdac1
pcm2: <HDA Conexant CX20590 PCM #1 Analog> at cad 0 nid 1 on hdac1
usbus0: 12Mbps Full Speed USB v1.0
usbus1: 480Mbps High Speed USB v2.0
usbus2: 12Mbps Full Speed USB v1.0
usbus3: 480Mbps High Speed USB v2.0
ada0 at ahcich0 bus 0 scbus0 target 0 lun 0
ada0: <M4-CT128M4SSD2 0009> ATA-9 SATA 3.x device
ada0: 300.000MB/s transfers (SATA 2.x, UDMA5, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 122104MB (250069680 512 byte sectors: 1H 63S/T 16383C)
ada0: Previously was known as ad4
SMP: AP CPU #1 Launched!
Timecounter "TSC-low" frequency 12473693 Hz quality 800
ugen0.1: <ATI> at usbus0
uhub0: <ATI OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus0
ugen2.1: <ATI> at usbus2
ugen1.1: <ATI> at usbus1
uhub1: <ATI OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus2
uhub2: <ATI EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus1
ugen3.1: <ATI> at usbus3
uhub3: <ATI EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus3
GEOM: ada0s1: geometry does not match label (16h,63s != 1h,63s).
Root mount waiting for: usbus3 usbus2 usbus1 usbus0
uhub0: 5 ports with 5 removable, self powered
uhub1: 5 ports with 5 removable, self powered
Root mount waiting for: usbus3 usbus1
uhub2: 5 ports with 5 removable, self powered
uhub3: 5 ports with 5 removable, self powered
Root mount waiting for: usbus3 usbus1
ugen3.2: <Bison Corp.> at usbus3
ugen0.2: <Broadcom Corp> at usbus0
Root mount waiting for: usbus3
ugen3.3: <Generic> at usbus3
Trying to mount root from ufs:/dev/ada0s1a [rw]...
ubt0: <Broadcom Corp Broadcom Bluetooth 2.1 Device, class 224/1, rev 2.00/4.72, addr 2> on usbus0
WARNING: attempt to domain_add(bluetooth) after domainfinalize()
WARNING: attempt to domain_add(netgraph) after domainfinalize()
Lenovo's S205 dmesg fingerprint

Additional surprise:

Sine the Lenovo posses a AHCPI SATA controller (only), the FreeBSD people decided to make it more comfortable to standard users by symlinking the device nodes to standard ATA hardware:

lrwxr-xr-x 1 root wheel 4 Feb 25 19:25 ad4 -> ada0
lrwxr-xr-x 1 root wheel 6 Feb 25 19:25 ad4s1 -> ada0s1
lrwxr-xr-x 1 root wheel 7 Feb 25 19:25 ad4s1a -> ada0s1a
lrwxr-xr-x 1 root wheel 7 Feb 25 19:25 ad4s1b -> ada0s1b
lrwxr-xr-x 1 root wheel 7 Feb 25 19:25 ad4s1d -> ada0s1d
lrwxr-xr-x 1 root wheel 7 Feb 25 19:25 ad4s1e -> ada0s1e
lrwxr-xr-x 1 root wheel 7 Feb 25 19:25 ad4s1f -> ada0s1f
lrwxr-xr-x 1 root wheel 7 Feb 25 19:25 ad4s1g -> ada0s1g
crw-r----- 1 root operator 0, 78 Feb 25 19:25 ada0
crw-r----- 1 root operator 0, 80 Feb 25 19:25 ada0s1
crw-r----- 1 root operator 0, 82 Feb 25 20:25 ada0s1a
crw-r----- 1 root operator 0, 84 Feb 25 20:25 ada0s1b
crw-r----- 1 root operator 0, 86 Feb 25 20:25 ada0s1d
crw-r----- 1 root operator 0, 88 Feb 25 20:25 ada0s1e
crw-r----- 1 root operator 0, 90 Feb 25 20:25 ada0s1f
crw-r----- 1 root operator 0, 92 Feb 25 20:25 ada0s1g
FreeBSD's symlinked AHCPI devices

The reason here is to provide compatibiity with current harware on a name space level. However, the current paradigm is to use labels instead of device nodes. Assume you have setup your OS on a hard disk and now (physically) remove this, while putting it into a USB case. Current computer hardare permits you to boot from that disk; however /etc/fstab is usesless, pointing to the wrong devices. However, Labels (assigned to physical devices by means of the disklabel program) may sustain this situation and allow you to boot your OS regardless.

Caution:GPT labels and OS disk labels are different itemes. Currently, GPT labels are simply disregarded by the OS.

Getting it done: FreeBSD on Lenovo S205

Devices and Geometries

Before we carry on, lets understand how gpt is working while taking a look at it's output:

GPT geometries

Some basic GPT geometry schemes and types

It is important to understand, that the partitioning scheme and an individual partition type are independent. Thus, a FreeBSD data partitition can be raised within the EFI scheme without a problem. The partition is recorded in the GPT header. However, the OS Kernel needs to understand the scheme or geometry as well.

For (Free)BSD two different types do exist:

  1. The legacy freebsd type, typically used for legacy BIOS systems, called a slices. Within a slice, you define mount points.
  2. The EFI related freebsd-boot, freebsd-swap, and freebsd-data type. Those partitions are directly accessible as mount points to the OS, provided that the kernel understands this geometry scheme.

Another useful (but irritating) aspect of the GPT partitioning, is the fact to assign serveral boot partitions and to label those as boot partition; again independent of the particular type.

This relationship is nicely expressed on the gpart page, but ...

The incomplete manual pages

FreeBSD 9 provides a very helpful man page of gpart including some examples how to set up different partitioning schemes and how to make them bootable.
However, the version which is accessible on FreeBSD.org lacks this kind of information and just references FreeBSD's 8 ones. Thus, you can download the most update gpart man page.

FreeBSD's GPT partitioning scheme

With this information, it is straightforward to generate -- within the EFI scheme -- the required FreeBSD partition types, was discussed by B0rken. In my case, on the Lenovo S205, the final GPT setup had this structure:

FreBSD GPT scheme

FreeBSD GPT scheme are gparting

I need to mention, that of course I chose the mount points in /etc/fstab accordingly. Thus, it looked greet ... until the reboot.

The success: Don't trust anybody

Certainly, I would not need to set up this web page, it things simply worked. However, there was no way to convice the Lenovo's BIOS to boot FreeBSD. It always tried to fall-back to PXE boot. Why ?

The simple Why ? is a delicate question, I can't answer this totally convinced. But after a lot of installation iterations, I have the following hypothesis:

  1. The 'Windows Boot Banager' section checks for the GPT presence and the existance of the Microsoft boot partition at LBA = 2048. Accessing this partition in FAT mode, it tries to start the OS from here.
  2. The other option in the boot menue -- in my case the ATA HDD0: M4-CT120M4SSD2' -- does however not support GPT but rather relies on the legacy BIOS settings of the disk.

Thus, in the case of the Lenovo S205, a *working* geometry for FreeBSD is the following:

$ gpart show ada0
=>       63    250069617    ada0   MBR (119G)
         63    249561081    1      freebsd [active] (119G)
         249561144 508536 - free - (248M)
The finally working FreeBSD disk layout on the Lenovo S205

Here, you see, that the disk is effectively just setup in the MBR scheme and the standard BSD slice freeebsd is used.

It would have saved my some night shifts trying to setup FreeBSD and perhaps as many hours to create this web page ...

The simpler way: sysinstall

Missing drivers and malfunctions of FreeBSD 9

A further trial: PC-BSD 9 and the Linux case

Lessons learned