diff options
author | Simon Rettberg | 2014-02-19 19:50:46 +0100 |
---|---|---|
committer | Simon Rettberg | 2014-02-19 19:50:46 +0100 |
commit | 3c185578e17acb79216b4a573e0c8af9671a6c45 (patch) | |
tree | 113c8936f86b9598444e5b31b067675b3f9cbcac /remote/rootfs/rootfs-stage31 | |
parent | [openslx] Check if mksquashfs supports xz, fall back to default compression i... (diff) | |
download | tm-scripts-3c185578e17acb79216b4a573e0c8af9671a6c45.tar.gz tm-scripts-3c185578e17acb79216b4a573e0c8af9671a6c45.tar.xz tm-scripts-3c185578e17acb79216b4a573e0c8af9671a6c45.zip |
Support loading selected drm gfx drivers only, based on pci ids
Diffstat (limited to 'remote/rootfs/rootfs-stage31')
7 files changed, 130 insertions, 33 deletions
diff --git a/remote/rootfs/rootfs-stage31/data/etc/modprobe.d/vmwgfx-fbdev.conf b/remote/rootfs/rootfs-stage31/data/etc/modprobe.d/vmwgfx-fbdev.conf new file mode 100644 index 00000000..ebc4b49c --- /dev/null +++ b/remote/rootfs/rootfs-stage31/data/etc/modprobe.d/vmwgfx-fbdev.conf @@ -0,0 +1,5 @@ +# when vmwgfx is loaded via modprobe in stage31, this conf file is read, +# enables fbdev support for vmware so that +# fb doesnt break when switching tty's in minilinux running inside vmware +options vmwgfx enable_fbdev=1 + diff --git a/remote/rootfs/rootfs-stage31/data/inc/drm.functions b/remote/rootfs/rootfs-stage31/data/inc/drm.functions new file mode 100644 index 00000000..666f22a9 --- /dev/null +++ b/remote/rootfs/rootfs-stage31/data/inc/drm.functions @@ -0,0 +1,71 @@ + +# pass module name(s) relative path in /lib/modules with .ko extension, or special like @nvidia or @amd +load_gfx () { + local MOD FILES OFFSET RETVAL + RETVAL=1 # default: failure + while [ $# -gt 0 ]; do + MOD=$(echo $1) # trim :) + shift + [ -z "$MOD" ] && continue + if [ "x${MOD}" != "x${MOD#@}" ]; then + # starts with '@' - special + OFFSET=$(( ${#MOD} + 2 )) + FILES=$( grep "^$MOD\s" "/drm.cfg" | cut -c ${OFFSET}- ) + [ -z "$FILES" ] && drop_shell "Could not find entry for special $MOD" + if load_gfx $FILES; then + RETVAL=0 + else + # loading special case failed, try fallback if found + MOD="${MOD}_fallback" + OFFSET=$(( ${#MOD} + 2 )) + FILES=$( grep "^$MOD\s" "/drm.cfg" | cut -c ${OFFSET}- ) + [ -n "$FILES" ] && load_gfx $FILES && RETVAL=0 + fi + else # regular module name or filename + if [ "x${MOD%.ko}" == "x${MOD}" ]; then + # regular module name + modprobe "$MOD" && RETVAL=0 + else + # a .ko file + insmod "/lib/modules/$MOD" && RETVAL=0 + fi + fi + done + return $RETVAL +} + +setup_gfx () { + local KERN RETVAL CARD CARDS SUCCESS FILES DRM + # check which driver to load + CARDS=$(lspci | grep 'Class 03' | awk '{print $4}') + if [ -e "/drm.cfg" ] && [ -n "$CARDS" ]; then + SUCCESS="yes" + for CARD in $CARDS; do + # look up exact pci id of this card + echo Trying exact matching for drm drivers for $CARD + FILES=$(grep "^$CARD\s" "/drm.cfg" | cut -c 11-) + load_gfx $FILES && continue + # failed... try vendor id only + CARD=$(echo $CARD | cut -c 1-4) + echo Trying vendor matching for drm drivers for $CARD + FILES=$(grep "^$CARD\s" "/drm.cfg" | cut -c 6-) + load_gfx $FILES && continue + # everything failed for this card + echo Unknown PCI vendor id: $CARD + SUCCESS="no" + done + [ "x$SUCCESS" == "xyes" ] && return 0 + fi + # braindead fallback + echo "At least one gfx card has no known drm drivers.... will load them all :/" + KERN=$(uname -r) + RETVAL=1 + [ -z "$KERN" ] && KERN=$(ls '/lib/modules' | grep '\.' | tail -n 1) + for DRM in $(find "/lib/modules/$KERN/kernel/drivers/gpu/drm" -name "*.ko"); do + DRM="$(basename "$DRM")" + DRM="${DRM%.ko}" + modprobe "$DRM" && RETVAL=0 + done + return $RETVAL +} + diff --git a/remote/rootfs/rootfs-stage31/data/inc/functions b/remote/rootfs/rootfs-stage31/data/inc/functions index 161533ef..f07acc7d 100644 --- a/remote/rootfs/rootfs-stage31/data/inc/functions +++ b/remote/rootfs/rootfs-stage31/data/inc/functions @@ -11,6 +11,10 @@ # drop_shell "This is your error message." # drop_shell() { + if [ -n "$MUTED_OUTPUT" ]; then + exec 1>&4 2>&5 + reset + fi [ $# -gt 0 ] && echo $@ echo "CTRL + D will continue booting." setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' diff --git a/remote/rootfs/rootfs-stage31/data/init b/remote/rootfs/rootfs-stage31/data/init index 95495684..368b3a64 100755 --- a/remote/rootfs/rootfs-stage31/data/init +++ b/remote/rootfs/rootfs-stage31/data/init @@ -56,25 +56,17 @@ for opts in ${KCL}; do esac done -setup_gfx () { - # read graphic and network adaptor configuration (without proprietary drivers yet) - # TODO: most ugly hack ever... needs to be improved when we add prop drivers - for DRM in /lib/modules/*/kernel/drivers/gpu/drm/*.ko /lib/modules/*/kernel/drivers/gpu/drm/*/*.ko; do - DRM="$(basename "$DRM")" - DRM="${DRM%.ko}" - #echo "Trying to load module $DRM" - modprobe "$DRM" 2>/dev/null - done - # start some kind of splash screen if activated - [ $SPLASH -eq 1 ] && setsid fbsplash -x -c -s /etc/splash.ppm -} - -if [ $SPLASH -eq 1 ]; then - exec 3>&1 4>&2 > /dev/null 2>&1 - echo "1 1 0 1" > /proc/sys/kernel/printk - setup_gfx +. "/inc/drm.functions" + +if [ "$SPLASH" -eq 1 ]; then + if setup_gfx; then + echo "1 1 0 1" > /proc/sys/kernel/printk + exec 4>&1 5>&2 > /dev/null 2>&1 + MUTED_OUTPUT=1 + setsid fbsplash -x -c -s /etc/splash.ppm + fi else - setup_gfx & + setup_gfx fi @@ -126,7 +118,7 @@ done echo "Switching root...." echo "$bench_result" > "${FUTURE_ROOT}/opt/openslx/.benchmark" # Prepare environment (HOME is needed as a hack for nss_ldap with ssl and no caching) -unset BOOT_IMAGE initrd KCL ip slxbase slxsrv IPINFO vga ip MAC BOOTIF DEBUG OLDPWD +unset BOOT_IMAGE initrd KCL ip slxbase slxsrv IPINFO vga ip MAC BOOTIF DEBUG OLDPWD MUTED_OUTPUT export HOME=/ export init="/usr/lib/systemd/systemd" export recovery= diff --git a/remote/rootfs/rootfs-stage31/rootfs-stage31.build b/remote/rootfs/rootfs-stage31/rootfs-stage31.build index f3eab5b6..3711e16d 100644 --- a/remote/rootfs/rootfs-stage31/rootfs-stage31.build +++ b/remote/rootfs/rootfs-stage31/rootfs-stage31.build @@ -4,6 +4,7 @@ fetch_source() { } build() { + local COPYLIST BIN_LOCATION DRM_MODULES FILE BIN MODNAME PCI_FILE ALIAS VENDOR DEVICE COPYLIST="list_binaries_and_files" [ -e "$COPYLIST" ] && rm -f "$COPYLIST" for BIN in $REQUIRED_BINARIES; do @@ -11,14 +12,38 @@ build() { [ -z "$BIN_LOCATION" ] && perror "Cannot find $BIN" get_link_chain "$BIN_LOCATION" >> "$COPYLIST" done - for FILE in $REQUIRED_FILES; do - get_link_chain "$FILE" >> "$COPYLIST" - done mkdir -p "$MODULE_BUILD_DIR/lib" find /lib /lib64 /usr/lib /usr/lib64 \( -name "libnss_dns*" -o -name "libresolv*" \) -exec cp -a {} "$MODULE_BUILD_DIR/lib/" \; tarcopy "$(cat "$COPYLIST" | sort -u)" "$MODULE_BUILD_DIR" + + # generate drm module loading database + pinfo "Generating PCI ID database for DRM drivers" + DRM_MODULES="$MODULES_DIR/kernel/build/lib/modules/$SYS_UTS_RELEASE/kernel/drivers/gpu/drm" + PCI_FILE="$MODULE_BUILD_DIR/drm.cfg" + [ -d "$DRM_MODULES" ] || perror "DRM dir not found at $DRM_MODULES" + cp "$MODULE_DIR/templates/drm.cfg" "$PCI_FILE" || perror "Could not copy drm.cfg from templates dir" + echo "# -- generated from kernel $SYS_UTS_RELEASE modules:" >> "$PCI_FILE" + for FILE in $(find "$DRM_MODULES" -name "*.ko"); do + MODNAME=$(basename "$FILE") + MODNAME=${MODNAME%.ko} + [ -z "$MODNAME" ] && perror "$FILE equals empty modname" + echo "# $MODNAME" >> "$PCI_FILE" + for ALIAS in $(modinfo "$FILE" | grep '^alias:' | grep -o 'pci:v.*' | tr '[A-F]' '[a-f]'); do + VENDOR=$(echo $ALIAS | cut -c 10-13) + if [ "x$(echo $ALIAS | cut -c 15)" == "x*" ]; then + # device wildcard + grep -q -i "^${VENDOR}\s" "$PCI_FILE" && continue + echo "${VENDOR} $MODNAME" >> "$PCI_FILE" + else + # specific device + DEVICE=$(echo $ALIAS | cut -c 19-22) + grep -q -i "^${VENDOR}:${DEVICE}\s" "$PCI_FILE" && continue + echo "${VENDOR}:${DEVICE} $MODNAME" >> "$PCI_FILE" + fi + done + done } post_copy() { @@ -29,13 +54,6 @@ post_copy() { copy_kernel_modules copy_firmware copy_kernel - - # when vmwgfx is loaded via modprobe in stage31, this conf file is read, - # enables fbdev support for vmware so that - # fb doesnt break when switching tty's in minilinux running inside vmware - # TODO: Why isn't this a simple static file in this module's data dir? - mkdir -p "$TARGET_BUILD_DIR/etc/modprobe.d" - echo "options vmwgfx enable_fbdev=1" > "${TARGET_BUILD_DIR}"/etc/modprobe.d/vmwgfx-fbdev.conf } # @@ -52,8 +70,5 @@ generate_rootfs() { # copy libc and ld-linux tarcopy "$(list_basic_libs)" "${TARGET_BUILD_DIR}" - - # copy required files - tarcopy "${REQUIRED_FILES}" "${TARGET_BUILD_DIR}" } diff --git a/remote/rootfs/rootfs-stage31/rootfs-stage31.conf b/remote/rootfs/rootfs-stage31/rootfs-stage31.conf index 02887e69..4b638678 100644 --- a/remote/rootfs/rootfs-stage31/rootfs-stage31.conf +++ b/remote/rootfs/rootfs-stage31/rootfs-stage31.conf @@ -68,8 +68,12 @@ REQUIRED_LIBRARIES=" libnss_dns libresolv " -REQUIRED_FILES=" +REQUIRED_SYSTEM_FILES=" /etc/protocols /etc/services /etc/localtime " +REQUIRED_FILES=" + /drm.cfg +" + diff --git a/remote/rootfs/rootfs-stage31/templates/drm.cfg b/remote/rootfs/rootfs-stage31/templates/drm.cfg new file mode 100644 index 00000000..f0a9db0c --- /dev/null +++ b/remote/rootfs/rootfs-stage31/templates/drm.cfg @@ -0,0 +1,6 @@ +# nvidia +10de:0193 @nvidia +# aliases +@nvidia nvidia/nvidia.ko nvidia/nvidia-uvm.ko +@nvidia_fallback nouveau + |