Linux on MacBook Air with NVIDIA drivers

In order to use the proprietary NVIDIA driver on a MacBook Air 3,1 (11-inch, late 2010) with the NVIDIA GeForce 320M chipset booting openSUSE Leap 42.1 in EFI mode, create the file /etc/grub.d/01_enable_vga.conf with the following content:

#!/bin/sh
set -e

# Initialize the PCI-E registers of MBA 3,1 for the nvidia driver

cat << EOF
btrfs-mount-subvol /dev/sda3 /boot/grub2/x86_64-efi /@/boot/grub2/x86_64-efi
insmod setpci
setpci -s "00:17.0" 3e.b=8
setpci -s "02:00.0" 04.b=7
EOF

and run grub2-mkconfig -o /boot/grub2/grub.cfg to update the bootloader configuration. Be aware that you might need to determine the PCI bus ids for your machine first by running lshw -businfo -class bridge -class display as described in this post on askubuntu. (Please note that using only the setpci command as suggested in that post for Ubuntu systems does not suffice on openSUSE systems, because on this system the setpci functionality is provided as a separate GRUB module and must be loaded explicitly with the insmod command; since the GRUB modules are not installed on the boot partition, their location has to be mounted first using the btrfs-mount-subvol command.)

Reboot and verify that the settings have actually been applied by running the setpci command on the command line as root without the part after the equal sign (e.g. setpci -s "00:17.0" 3e.b). This should return the values assigned before, i.e. 8 or 7 respectively.

Then proceed installing the nvidia driver by choosing the appropriate package on the openSUSE Community website. In my case (NVIDIA GeForce 320M), that means choosing the „Geforce 8 series and later“ option.

My i3 dual screen workflow

Using the i3 tiling window manager on two screens („outputs“) can be challenging. The number of workspaces grows twice as fast than with a single screen setup and it is easy to lose track of the numbers and contents of workspaces. For me personally it is more intuitive to remember a certain sequence of workspaces on each screen, which seemingly extends above and below the workspace presently displayed. (It may be that this intuition has been coined by using the GNOME Shell over extended periods.)

In order to achieve a comparable user experience within i3, I use the following Python script with the keybindings presented below. The script is inspired by an article on the i3 homepage by user captnfab. It has one dependency: ziberna/i3-py, which can be installed with pip3 install i3-py. As is apparent from the keybindings, Ctrl+Alt+Up/Down are used to switch the present workspace on the focused output. With the same keys together with +Shift you can take the focused window with you.

#!/usr/bin/python3
#
# i3-switch-workspace.py
# by Fabian Stanke
#
# Sequentially switch workspaces on present output

import i3
import argparse

parser = argparse.ArgumentParser(
description='i3 workspace switcher.')

parser.add_argument(
'--move', action='store_true',
help='take the focused container with you when moving.')
parser.add_argument(
'direction', choices=['next', 'prev'],
help='defines in which direction to switch.')

args = parser.parse_args()

workspaces = i3.get_workspaces()

# Determine focused workspace (and thus the focused output)
focused_ws = next((w for w in workspaces if w['focused']))

# Collect all workspaces of the focused output
ws_names = list(w['name']
for w in workspaces
if w['output'] == focused_ws['output'])

# Determine position of focused worspace in that collection
idx = ws_names.index(focused_ws['name'])
target = focused_ws['name']

if args.direction == 'next':
# Determine next workspace

if (idx + 1 < len(ws_names)):
target = ws_names[idx + 1]
else:
# Determine last number used on this output
maxidx = 1
# Determine unused numbers
used = {}
for w in workspaces:
try:
widx = int(w['name'])
used[widx] = True
if w['output'] == focused_ws['output']:
maxidx = max(widx, maxidx)
except:
continue
# Increment to create new name
while used.get(maxidx, False):
print(maxidx)
maxidx += 1
target = str(maxidx)

elif args.direction == 'prev':
# Determine previous workspace

if (idx - 1 >= 0):
target = ws_names[idx - 1]
#else remain at first workspace

if args.move:
# Move the focused container to the target workspace first
i3.command('move', 'container to workspace ' + target)

# Switch
#print("switch to " + target)
i3.workspace(target)

My preferred keybindings to actually use the above script are:

bindsym Ctrl+Mod1+Down exec i3-switch-workspace.py next
bindsym Ctrl+Mod1+Up exec i3-switch-workspace.py prev
bindsym Ctrl+Mod1+Shift+Down exec i3-switch-workspace.py --move next
bindsym Ctrl+Mod1+Shift+Up exec i3-switch-workspace.py --move prev

Nur „echte“ Benutzerkonten anzeigen

Um am Login Bildschirm von Fedora nur jene Konten anzuzeigen, die sich in letzter Zeit eingeloggt haben, muss man nur eine kleine Änderung an der /etc/gdm/custom.conf Datei vornehmen:

--- old/custom.conf	2011-07-07 09:35:01.462829111 +0200
+++ new/custom.conf	2011-07-07 09:30:27.146258540 +0200
@@ -7,6 +7,7 @@
 [xdmcp]
 
 [greeter]
+IncludeAll=false
 
 [chooser]
 

Damit werden nicht oder zB nur per scp genutzte Benutzernamen ausgeblendet.

Fedora 15 on NVIDIA NVS 3100M

In an earlier post, I already wrote about how to install the proprietary video driver on Fedora. In a brief update I suggested to change the acpi_sleep kernel option to accomplish proper display wake-up from standby. Unfortunately, that solution doesn’t work reliably in my experience. Today I found a solution that seems to successfully work around the problem of the black screen by waking up the screen „manually“.

Gernot Walzl wrote a „nasty workaround“ (quoting himself) in the form of the following script:

#!/bin/sh

# nvidia_dpms_fix.sh
# 2011-06-12
# by Gernot WALZL

# nasty workaround for nvidia drivers to resume from dpms off/suspend

export DISPLAY=:0

getXauthority () {
  export XAUTHORITY=$(ps -C X -f | grep "$DISPLAY" \
    | sed -n 's/.* -auth \([^ ]*\).*/\1/p')
}

handle_line () {
  if echo "$1" | grep -e "(EE) NVIDIA.* DisplayPort link training failed" \
      > /dev/null; then
    getXauthority
    xset dpms force on
  fi
}

tail --follow=name /var/log/Xorg.0.log --retry --lines=1 2> /dev/null \
  | while read line; do
    handle_line "$line"
  done

To actually make this do its job, I copied it into /usr/local/bin, made it executable and created an autostart entry for GNOME 3 by saving the following lines under ~/.config/autostart/nvidia_dpms_fix.sh.desktop

[Desktop Entry]
Type=Application
Exec=/usr/local/bin/nvidia_dpms_fix.sh
Hidden=false
X-GNOME-Autostart-enabled=true
Name=NVidia DPMS fix
Comment=Wakes up the display properly

I believe the problem that is being worked around is indicated by a line in the Xorg.0.log:

(WW) NVIDIA(GPU-0): AUO (DFP-3): Failed to set DisplayPort power state

Although I could only test this on my machine (HP EliteBook 8440p), with some luck this works for all cases where a similar log message is found.