summaryrefslogtreecommitdiff
path: root/content/blog/archlinux-macbook-a1211.md
blob: 3df776ab2ef30b2051a99ba22aa40322eab3ee83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
+++
title = "Archlinux on a MacBook Pro 15'' Model A1211"
categories = [ "Operating System", "Archlinux", "MacBook" ]
date = "2018-11-12T16:55:39+01:00"
thumbnail = "/images/blog/archlinux-macbook-a1211/macbook-A1211.jpg"
+++

## History

I got an old Mac from a collegue at work. Apple decided not to
support those devices anymore, anyway, they date back to 2006.
I think, it's a pitty, because this Mac has a solid case, a pretty fast
64-bit processor (sorry Archlinux32, no test machine for you) and
a graphic chip which is not melting away like in later models
(I don't name brand names here)..

Here the specifications:

* 2.3 GHz Intel Core 2 Duo
* 2GB 667 DDR2 SDRAM
* OSX 10.6.8
* ATI Radeon X1600 256 MB RAM, 1440x900, 32 bit

I didn't try any Sierra OS X hacks (or installing a Capitan, rumours are,
it works even on such an old laptop) on old hardware and besides,
Archlinux is a better choice for a developer on a Mac. Although
there are still MacPorts for OS X 10.6.x (no Brew though), it can be
quite painful to get something compiled on a Mac OS that old.

As we will see later, we want to keep OS X around to be able to
change some settings, extract some firmware, etc.

## Installation

### Prepare for dual installation

We have a whooping 120 GB hard disk space, so I shrank the OS X partition to 64 GB.
This can be done in the *Disk Utility.app*, just leave EFI in peace, set OSX to
64 GB and assign the rest of the hard disk as free space.

Prepare the USB stick for installation, I had no luck with the standard ISO,
but a hand-crafted USB-stick worked:

```
hdiutil convert -format UDRW -o archlinux-2018.09.01-x86_64.img archlinux-2018.09.01-x86_64.iso 
dd if=archlinux-2018.09.01-x86_64.dmg of=/dev/disk2 bs=1m
```

### EFI boot

I used [ReFIT for MAC](http://refit.sourceforge.net/) to improve the
somewhat limited EFI environment of an early Mac (don't get me wrong, it's
pretty impressive that such an old machine already had EFI, but nowadays this
EFI shows its age).

The firmware is a 32-bit EFI without a proper command line mode,
causing trouble all along. I didn't take ReFind as I didn't expect the 
32-bit EFI to be currently supported, especially as I see Tianocore
failing to build with more modern 32-bit binutils and gcc.

I installed a 32-bit GRUB onto the EFI partition as a second boot option
along to OSX. This one then boots ArchLinux. This is easier than trying
to load a 64-bit kernel with kernel EFI stub support from an 32-bit
EFI environemnt with systemd-boot.

### ATI VESA BIOS

I didn't want to boot into legacy mode to make the VGA BIOS visible, so
I got a nice problem during KMS switching during early boot: the
graphical output just froze. The irony here is that modern Linux and Xorg
don't care at all about the old VGA/VESA BIOS, but they do so for KMS,
where the kernel has to rely on 16-bit firmware functions in the video
BIOS to program the video chip for graphics mode.

All I got was the following kernel and Xorg error messages:

```
[2.052705] [drm] initializing kernel modesetting (RV530 0x1002:0x71C5 0x106B:0x0080 0x00).
[2.052742] radeon 0000:01:00.0: Invalid PCI ROM header signature: expecting 0xaa55, got 0xa1a1
[2.052817] [drm:radeon_get_bios [radeon]] *ERROR* Unable to locate a BIOS ROM
[2.052825] radeon 0000:01:00.0: Fatal error during GPU init
[2.053037] radeon: probe of 0000:01:00.0 failed with error -22
...
[31.041] (EE) open /dev/dri/card0: No such file or directory
```

So this basically translates to: "I don't have a direct rendering interface,
because there is no video card, because there is no BIOS for that card".

The key idea was to extract the VESA BIOS on a distribution which handles
the KMS switching correctly (in my case an old Ubuntu 10).

```
dd if=/dev/mem of=vbios.bin bs=65536 skip=12 count=1
```

Verify that you actually got the right firmware. There is an error message
when booting the kernel saying:

```
[2.052742] radeon 0000:01:00.0: Invalid PCI ROM header signature: expecting 0xaa55, got 0xa1a1
```

so we expect to find that signature at the beginning of the *vbios.bin* file:

```
hexdump -C vbios.bin | head -n 1
00000000  55 aa 7d e9 7f 02 00 00  00 00 00 00 00 00 00 00  |U.}.............|
```

This firmware comes into */lib/firmware/radeon/vbios.bin* to be available during
boot.

The next problem was that the radeon module in the Linux kernel doesn't
know about this firmware. There is a patch in https://bugs.freedesktop.org/show_bug.cgi?id=26891
for older kernels, but it translates easily to the latest kernel. All
it does is to load the *vbios.bin* file from the right place, when all the other
options fail.

My version of the module is [here](/text/blog/archlinux-macbook-a1211/radeon_bios.c), check
out function *radeon_read_bios_from_firmware* and the code calling that function.


In order to use the Radeon driver for KMS as early as possible,
I put it into the init-RAM-disk:

So, I added to */etc/mkinitcpio.conf* and rebuilt the ram disks:

```
MODULES=(radeon)
FILES=(/usr/lib/firmware/radeon/vbios.bin)
```

### "Total Darkness" after 10 minutes

Everything was running smoothly.. for about 10 minutes. Then my LCD display
just went pitch black.

Setting the brightness manually didn't help:

```
xrandr --output LVDS --brightness 1
```

(it did work later though to set the brightness between 0.0 and 1.0)

The trick is to tell the radeon module to handle the LCD backlight, not
one of the Apple brightness modules. In */etc/modprobe.d/radeon.conf* put:

```
options radeon backlight=1
```

Also handy is the https://aur.archlinux.org/packages/brightd/, though
I think also systemd-backlight can nowadays at least save the brightness
across reboots and suspends.

### Function keys or special keys

If you don't need the special keys for controlling the volume and brightness but instead the old
Fxx function keys, add the following to */etc/modprobe.d/hid_apple.conf*:

```
options hid_apple fnmode=2
```

### Camera

Here we come to iSight and why we need OS X around to extract the proper
firmware.

https://wiki.archlinux.org/index.php/Mac#Webcam has a really nice walkthrough.

Shortly, you need https://aur.archlinux.org/packages/hfsprogs/ to mount the HFS
partition. There you will find a file called *AppleUSBVideoSupport* in
*/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBVideoSupport.kext/Contents/MacOS*.

You will also need https://aur.archlinux.org/packages/isight-firmware-tools/.
It contains tools to extract the file containg the firmware called *isight.fw*
from *AppleUSBVideoSupport*.

Finally it contains an udev rule in */etc/udev/rules.d/isight.rules* which then makes
sure the firmware is also loaded on startup during detection of the camera via udev.

### Wifi

The wireless card was supported without any problems. Just some channels
were not visible.

Install *wireless-regdb* and make sure to enable the proper regulatory domain in
*/etc/conf.d/wireless-regdom*:

```
WIRELESS_REGDOM="CH"
```

The regulatory domain has to be set properly, put it into */etc/modprobe.d/regdom.conf*:

```
options cfg80211 ieee80211_regdom=CH
```

(CH is for Switzerland, pick your own country here)

Note: I think my method is deprecated and you can also specify the
regulatory domain directly in wpa_supplicant.conf, but then how
to use systemd-networkd with that?

### Fans and sensors

[macfanctl](https://aur.archlinux.org/packages/macfanctld/) from the AUR works nicely,
also lm_sensors had no problems to get the sensor data.

### Power consumption

cpupower seems to work fine. Just make sure the 'p4-clockmod' module is loaded
at boot.

Note: I didn't try powertop or other tweaks. I got some worriesome ticking
noises of the hard disk after a suspend and my battery is not that powerful
anyway, so I'll run mostly on net power.

### Mouse buttons

Managers might like to use only one mouse button. Also keyboard fanatics may
be happy by just switching off the mousepad completly.

The one button mouse is a disaster for people being used to Xorg copy-
paste or Oberon enthusiasts used to three mouse buttons.

Scrolling with two fingers is nice, but per default they are enabled only for up and down.
I enabled also scrolling to the left and right. Besides, the keyboard is missing
PageUp, PageDown keys, which is a usability nightmare when you want to
scroll bigger source code files or web pages (yes, I know there is Fn-Page,
but having Ctrl, Alt, Meta and Fn all on the same spot doesn't make it
easier to find the right one).

Side note: I'm using *Fn* for keyboard scrolling (PgUp, PgDown), *Ctrl* for Wordstar short-cuts, "Alt" for
Notion (window manager) shortcuts, and they are really _CLOSE_ together..

Change */etc/X11/xorg.conf.d/50-synaptics.conf* as follows to your likings:
```
Section "InputClass"
	Identifier "Touchpad Catchall"
	Driver "synaptics"
	MatchIsTouchpad "on"
	Option "TapButton1" "0"
	Option "TapButton2" "3"
	Option "TapButton3" "2"
	Option "VertTwoFingerScroll" "1"
	Option "HorizTwoFingerScroll" "1"
	Option "ClickFinger2" = 0
	Option "ClickFinger3" = 0
EndSection
```

*TabButton1=1* only leads to all kind of frantic behaviour, because I
touch the touchpad by accident too often. *ClickButton* and *TapButton*
for the second and third button are just completly useless. Either no menu
appears for TapButton or a menu appears for ClickFinger, but I can no
longer do copy-pastes.

The default modifiers Ctrl, Alt, Meta don't do anything with the mouse
or just very weird stuff, like Alt-2-fingers jumps to the beginning of
my text.

For now, I choose TapButtons for copy-paste, as this is the function
I need most often.

I might add some Ctrl, Meta modifiers to get 2, 3 mouse button clicks later.

## Philosophical Outro

In a world where companies try hard to get people into their ecosystem (controlling
what users can do with the products they bought and own, what they can repair or let repair, what kind
of operating system and software they are supposed to use), I think, it's the
duty of any tech professional to invest some time to give old hardware back some
purpose (hence I'm also working on the Archlinux32 project). Also, throwing
away barely used machines, just because a company wants to earn billions, is an
ecological disaster. Remember, companies have been invented to make money, don't
get fooled by "we are there to make the world a better place" or any other marketing bs.
As the company which should not be named is quite good at this kind of business, I
expect all major vendors to follow soon. So that's why I keep a park of old machines
around and I'm not buying new machines since 10 years (I do buy old ones from Ebay though).

## References

* https://everymac.com/systems/apple/macbook_pro/specs/macbook-pro-core-2-duo-2.33-15-specs.html :
  specifications of the A1211 model
* [https://bugs.freedesktop.org/show_bug.cgi?id=26891](https://bugs.freedesktop.org/show_bug.cgi?id=26891): the patch to radeon.ko,
  enabling loading of file as VESA bios
* [https://bbs.archlinux.org/viewtopic.php?id=139511](https://bbs.archlinux.org/viewtopic.php?id=139511): some discussions about
  the VESA radeon topic in the Archlinux forum.
* https://wiki.archlinux.org/index.php/Mac#Webcam: how to make the camera work

## Addendum 19.2.2021

For kernel 5.7.6 updated version [here](/text/blog/archlinux-macbook-a1211/radeon_bios-5.7.6.c) .

Also a small walkthrough on how to update the module (in a most likely not too official way):

```
wget https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.7.6.tar.xz
tar xf linux-5.7.6.tar.xz
cd linux-5.7.6
make mrproper
# use the the configuration of the new kernel!
zcat /proc/config.gz > .config
sed -i 's/.*CONFIG_LOCALVERSION=.*/CONFIG_LOCALVERSION="-arch1-1"/g' .config
sed -i 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/g' .config
make oldconfig
make scripts prepare modules_prepare
# copy radeon_bios.c to drivers/gpu/drm/radeon
make -C . M=drivers/gpu/drm/radeon
rm -f /lib/modules/5.7.6-arch1-1/kernel/drivers/gpu/drm/radeon/radeon.ko.xz
xz -c drivers/gpu/drm/radeon/radeon.ko \
        > /lib/modules/5.7.6-arch1-1/kernel/drivers/gpu/drm/radeon/radeon.ko.xz 
depmod -av
mkinitcpio -P
cp /boot/initramfs-linux.img /mnt/efi/.
cp /boot/initramfs-linux-fallback.img /mnt/efi/.

# Archlinux kernel compilation
https://wiki.archlinux.org/index.php/Kernel/Traditional_compilation#Download_the_kernel_source
# build just one module
https://yoursunny.com/t/2018/one-kernel-module/
```

Where /mnt/efi is the VFAT rEFIt EFI partition which contains grub and the kernel
image and RAM disk.

## Addendum 18.6.2023

For kernel 6.3.8 updated version [here](/text/blog/archlinux-macbook-a1211/radeon_bios-6.3.8.c) .

## Addendum 22.10.2023

Tried a kernel 6.5.8 (still working with the 6.3.8 version of the radeon_bios patch avaiable
[here](/text/blog/archlinux-macbook-a1211/radeon_bios-6.3.8.c)).

Here is also another way to build the kernel and the patched radeon module:

```
mount /mnt/efi (before updating the kernel!)
pacman -Syyu
cp /boot/vmlinuz-linux /mnt/efi/vmlinuz-linux
cp /boot/initramfs-linux.img /mnt/efi/initramfs-linux.img
cp /boot/initramfs-linux-fallback.img /mnt/efi/initramfs-linux-fallback.img

pkgctl repo clone linux
cd linux
makepkg -do
cp ~/radeon_bios-6.3.8.c src/linux-6.5.8/drivers/gpu/drm/radeon/radeon_bios.c 
makepkg -s

cp pkg/linux/usr/lib/modules/6.5.8-arch1-1/kernel/drivers/gpu/drm/radeon/radeon.ko.zst \
  /lib/modules/6.5.8-arch1-1/kernel/drivers/gpu/drm/radeon/radeon.ko.zst 
depmod -av
mkinitcpio -P
cp /boot/initramfs-linux.img /mnt/efi/initramfs-linux.img
cp /boot/initramfs-linux-fallback.img /mnt/efi/initramfs-linux-fallback.img
```