Plan9/ThinkPad T420s
Finally, after a long time running 9front on virtual machines, it is time to get productive on real machines. ThinkPads are the best supported laptops in 9front because ThinkPads are what the developers use.
After some search the Lenovo ThinkPad T420s looked like a good candidate for my use case. There are still a few places that sell T420s, mine was purchased at refurbed.at, delivered swiftly, is as good as new, and has the following specifications:
- CPU (Intel® Core™ i5-2540M (2.6GHz, 3MB L3, 1333MHz FSB) (cpuid: AX 000206A7 CX 17BAE3FF DX BFEBFBFF))
- Graphics (Intel HD Graphics 3000 (integrated Sandy Bridge GPU))
- 1TB SSD hard drive (HP SSD S700 1TB R0522A1 HBSA41060500811)
- 1GB Ethernet (Intel 82579LM Gigabit, works)
- Wifi (Intel Centrino Advanced-N 6205 Taylor Peak, etheriwl (firmware: iwn-6005), works)
- Sound (Intel HD 6 Series/C200 Series, works)
- Three button mouse
Installation
At the time 9front release Mit Fruchtgeschmack was available. Simply follow the installation guide to get 9front up and running.
With a 1TB SSD drive the aim was to setup a
cwfs64x file system with
encrypted fsworm
, fscache
and other
partitions. The
documentation describing how to
setup encrypted disk partitions
is simple and worked out of the box.
The key thing to keep in mind after installation, when booting at the
bootargs
prompt, type !rc
to drop to a shell, and activate the
encrypted partitions with the following command:
% disk/cryptsetup -i /dev/sdE0/fsworm /dev/sdE0/fscache /dev/sdE0/other
Password: *********
% exit
After entering the password chosen during disk encryption setup type
exit
to resume booting.
At the bootargs prompt, enter local!/dev/fs/fscache
to continue
booting from the encrypted partition.
Setup
The following section describes additional setup and configuration
steps to simplify booting from an encrypted partition, enable wifi,
and audio, starting with my plan9.ini
.
Plan9.ini
% 9fs 9fat
% cat /n/9fat/plan9.ini
bootfile=9pc64
cryptdev=/dev/sdE0
bootargs=local!/dev/fs/fscache
nvram=#S/sdE0/nvram
ether1=type=iwl essid=0xBADC0FFE
audio0=hda
mouseport=ps2intellimouse
monitor=vesa
vgasize=1600x900x32
*acpi=1
tiltscreen=none
user=igor
sysname=pjw
Boot from Encrypted Partitions
The setup of encrypted partitions is well documented and straight
forward. Booting from them is a bit tedious though. Having to enter
!rc
at the bootargs
prompt and typing:
% disk/cryptsetup -i /dev/sdE0/^(fsworm fscache other)
Password: *********
% exit
…is not exactly swift. It would be nice if the boot procedure just prompted for the password required to decrypt the encrypted partition.
There are probably many ways to achieve this. I have settled on
adding a variable cryptdev
to plan9.ini
and modify
/sys/src/9/boot/bootrc
to automatically activate a previously
formatted AES-encrypted partition if that variable is set.
First, lets extend plan9.ini
with a variable cryptdev
, specifying
the device (/dev/sdE0
) containing encrypted cwfs
partitions:
% 9fs 9fat
% echo 'cryptdev=/dev/sdE0' >> /n/9fat/plan9.ini
Next, extend /sys/src/9/boot/bootrc
to activate AES-encrypted cwfs
partitions on the device defined in cryptdev
(diff highlighting the
changes):
% bind -ac /dist/plan9front /
% cd /usr/src
% hg diff .
diff -r d588a54f841a sys/src/9/boot/bootrc
--- a/sys/src/9/boot/bootrc Mon May 17 13:46:44 2021 -0700
+++ b/sys/src/9/boot/bootrc Sun May 23 00:53:48 2021 +0200
@@ -66,6 +66,14 @@
fn main{
mp=()
+
+ # disk encryption
+ if(! ~ $#cryptdev 0){
+ if(~ `{grep -c crypt /dev/fs/ctl} 0){
+ disk/cryptsetup -i $cryptdev/^(fscache fsworm other)
+ }
+ }
+
while(~ $#mp 0){
if(~ $#nobootprompt 0){
echo
After modifying /sys/src/9/boot/bootrc
as described above,
rebuild and
install the kernel to
activate the changes during boot:
% cd /sys/src/9/pc64
% mk install
…
% 9fs 9fat
% cp /amd64/9pc64 /n/9fat/
% fshalt -r
With this setup a password prompt will automatically appear during
boot if the variable cryptdev
is defined, and the encrypted
partition has not yet been activated.
Wifi
Wifi Firmware
A binary firmware blob (i.e. iwn-6005
) is required to enable Wifi.
Here is how to download and copy the firmware blob to /lib/firmware
:
% ramfs ; cd /tmp
% hget -o iwn-firmware-5.11p1.tgz \
http://firmware.openbsd.org/firmware/6.9/iwn-firmware-5.11p1.tgz
% tar xzf iwn-firmware-5.11p1.tgz
% cp firmware/iwn-6005 /lib/firmware
To make the firmware blob available at boot rebuild and install the kernel:
% cd /sys/src/9/pc64
% mk install
…
% 9fs 9fat
% cp /amd64/9pc64 /n/9fat/
% fshalt -r
This ‘packs’ the firmware blob into the boot kernel image, enabling boot via wifi.
Wifi Configuration
There are many ways how Wifi interfaces can be configured. My use case for WiFi ethernet is as follows:
-
When connected to wired ethernet, the WiFi interface is not bound and its IP stack remains unused.
-
If no wired ethernet is available, a list of
essid
s is printed during bootup so one can be selected. -
Finally, when working at home where the
essid
is constant, it is possible to define theessid
viaplan9.ini
resulting in fewer questions asked during boot.
The following script initialises WiFi ethernet accordingly:
% cat $home/bin/rc/initwifi
#!/bin/rc -e
rfork e
fn Help{ echo `{basename $0}^' [essid]' }
fn Dump{ grep node '#'l1/ether1/ifstats }
fn Ask{
echo -n $1
essid=`{dd -bs 64 -count 1 >[2]/dev/null}
}
fn Wifi{
ip/ipconfig ether /net/ether0 unbind
bind -b '#'l1 /net
aux/wpa -p2 -s $essid /net/ether1
ip/ipconfig -6
ip/ipconfig ra6 recvra 1 &
ip/ipconfig ether /net/ether1 &
wait
secstore=`{grep sys /net/ndb | awk -F'=' '{print $2}'}
cat /net/ndb
}
switch($#*){
case 0
if(~ $#essid 0){
echo Available wifi essids…
Dump
echo
Ask 'essid='
}
if(! ~ $#essid 0){
Wifi
}
case 1
essid=($1)
Wifi
case *
Help
Dump
}
A good place to call this script is for the terminal
case in lib/profile
:
% cat $home/lib/profile
…
switch($service){
case terminal
auth/factotum
webcookies
webfs
…
initwifi
^^^^^^^^
…
rio -i riostart
…
A prompt to select an essid
from a list just before starting rio
will be displayed. Hit enter to skip the selection or type in the
desired essid
. To avoid the prompt all together define essid
in
plan9.ini
.
The following transcript of the bootprocess highlights at what stage the essid
prompt appears:
% cat /dev/kmesg
…
/dev/sdE0: HP SSD S700 1TB
/dev/sdE0/9fat dos
/dev/sdE0/data
/dev/sdE0/fscache
/dev/sdE0/fsworm
/dev/sdE0/nvram
/dev/sdE0/other
/dev/sdE0/plan9
/dev/sdE1: MATSHITADVD-RAM UJ8A2 SB01
/dev/sdE2:
/dev/sdM0: MMC Host Controller
bootargs is (tcp, tls, il, local!device)[local!/dev/fs/fscache]
current fs is "main"
11 uids read, 6 groups used
63-bit cwfs as of Tue May 18 01:16:27 2021
last boot Fri Jun 4 02:14:31 2021
init: starting /bin/rc
warning: scanning for unoffered vesa modes
secstore password:
secstore
Available wifi essids…
node: 6c710d521720 1431 70 01 0xBADC0FFE
node: 6c710d521722 1431 70 01 0xBADGUEST
node: 6c710d521980 1431 110 01 0xBADC0FFE
node: 6c710d521982 1431 110 01 0xBADGUEST
essid=0xBADC0FFE
ip=10.5.5.99 ipmask=255.255.255.0 ipgw=10.5.5.5
sys=pjw
dom=pjw.home
dns=10.5.5.5
Note that the script assumes a protected wifi network is being joined,
requiring authentication and key exchange handled by aux/wpa
(see man 8 wpa).
Monitor
The following settings are used for the builtin screen:
term% 9fs 9fat
term% cat /n/9fat/plan9.ini
…
monitor=vesa
vgasize=1600x900x32
tiltscreen=none
…
Using an external monitor such as the LG ULTRAWIDE at 3440x1440
via the DisplayPort
is not working using vesa
, use igfx
instead.
To find out what resolutions are supported issue the following command:
term% @{rfork n; aux/realemu; aux/vga -m igfx -p}
…
edid name LG ULTRAWIDE
edid product 23266
edid serial 112436
edid version 1.4
edid mfrdate 2015.1
edid size (cm) 80x34
edid gamma 2.20
edid vert (Hz) 56-61
edid horz (Hz) 30000-90000
edid pclkmax 320000000
edid flags digital standby
edid 3440x1440@50Hz
clock=265.25
shb=3488 ehb=3520 ht=3600
vrs=1443 vre=1453 vt=1474
hsync=+ vsync=-
edid 3440x1440@60Hz
clock=319.75
shb=3488 ehb=3520 ht=3600
vrs=1443 vre=1453 vt=1481
hsync=+ vsync=-
…
The following command tries to use that resolution using igfx
:
term% @{rfork n; aux/realemu; aux/vga -m igfx -l '3440x1440'}
NOTE
: Before you issue the above command ensure you are in
a terminal and you can type fshalt
if anything goes wrong. Not
all of my external screens work with igfx
and once igfx
falls
over and the screen is black there is no recovery other than fshalt
…