summary refs log tree commit diff
path: root/installer/nixos-hardware-scan.pl
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2008-01-30 14:16:38 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2008-01-30 14:16:38 +0000
commit7363895f6d4e3e0806280b6548c706a19e7ab114 (patch)
tree1e01f97e3060fb708a1e708c1b6b2f2a45b9d595 /installer/nixos-hardware-scan.pl
parentc1f619a08780901def3f81f352a29f0711af0623 (diff)
downloadnixpkgs-7363895f6d4e3e0806280b6548c706a19e7ab114.tar
nixpkgs-7363895f6d4e3e0806280b6548c706a19e7ab114.tar.gz
nixpkgs-7363895f6d4e3e0806280b6548c706a19e7ab114.tar.bz2
nixpkgs-7363895f6d4e3e0806280b6548c706a19e7ab114.tar.lz
nixpkgs-7363895f6d4e3e0806280b6548c706a19e7ab114.tar.xz
nixpkgs-7363895f6d4e3e0806280b6548c706a19e7ab114.tar.zst
nixpkgs-7363895f6d4e3e0806280b6548c706a19e7ab114.zip
* Rewrote the hardware scanner in Perl.
svn path=/nixos/trunk/; revision=10405
Diffstat (limited to 'installer/nixos-hardware-scan.pl')
-rw-r--r--installer/nixos-hardware-scan.pl174
1 files changed, 174 insertions, 0 deletions
diff --git a/installer/nixos-hardware-scan.pl b/installer/nixos-hardware-scan.pl
new file mode 100644
index 00000000000..5b2f6692d86
--- /dev/null
+++ b/installer/nixos-hardware-scan.pl
@@ -0,0 +1,174 @@
+#! @perl@ -w
+
+use File::Spec;
+use File::Basename;
+
+
+my @kernelModules = ();
+my @initrdKernelModules = ();
+
+
+# Read a file, returning undef if the file cannot be opened.
+sub readFile {
+    my $filename = shift;
+    my $res;
+    if (open FILE, "<$filename") {
+        my $prev = $/;
+        undef $/;
+        $res = <FILE>;
+        $/ = $prev;
+        close FILE;
+        chomp $res;
+    }
+    return $res;
+}
+
+
+my $cpuinfo = readFile "/proc/cpuinfo";
+
+
+sub hasCPUFeature {
+    my $feature = shift;
+    return $cpuinfo =~ /^flags\s*:.* $feature( |$)/m;
+}
+
+
+# Detect the number of CPU cores.
+my $cpus = scalar (grep {/^processor\s*:/} (split '\n', $cpuinfo));
+
+
+# CPU frequency scaling.  Not sure about this test.
+push @kernelModules, "acpi-cpufreq" if hasCPUFeature "acpi";
+
+
+# Virtualization support?
+push @kernelModules, "kvm-intel" if hasCPUFeature "vmx";
+push @kernelModules, "kvm-amd" if hasCPUFeature "svm";
+
+
+# Look at the PCI devices and add necessary modules.  Note that most
+# modules are auto-detected so we don't need to list them here.
+# However, some are needed in the initrd to boot the system.
+
+sub pciCheck {
+    my $path = shift;
+    my $vendor = readFile "$path/vendor";
+    my $device = readFile "$path/device";
+    my $class = readFile "$path/class";
+    
+    my $module;
+    if (-e "$path/driver/module") {
+        $module = basename `readlink -f $path/driver/module`;
+        chomp $module;
+    }
+    
+    print "$path: $vendor $device $class";
+    print " $module" if defined $module;
+    print "\n";
+
+    if (defined $module) {
+        # See the bottom of http://pciids.sourceforge.net/pci.ids for
+        # device classes.
+        if (# Mass-storage controller.  Definitely important.
+            $class =~ /^0x01/ ||
+
+            # Firewire controller.  A disk might be attached.
+            $class =~ /^0x0c00/ ||
+
+            # USB controller.  Needed if we want to use the
+            # keyboard when things go wrong in the initrd.
+            $class =~ /^0x0c03/
+            )
+        {
+            push @initrdKernelModules, $module;
+        }
+    }        
+}
+
+foreach my $path (glob "/sys/bus/pci/devices/*") {
+    pciCheck $path;
+}
+
+
+# Idem for USB devices.
+
+sub usbCheck {
+    my $path = shift;
+    my $class = readFile "$path/bInterfaceClass";
+    my $subclass = readFile "$path/bInterfaceSubClass";
+    my $protocol = readFile "$path/bInterfaceProtocol";
+
+    my $module;
+    if (-e "$path/driver/module") {
+        $module = basename `readlink -f $path/driver/module`;
+        chomp $module;
+    }
+    
+    print "$path: $class $subclass $protocol";
+    print " $module" if defined $module;
+    print "\n";
+ 
+    if (defined $module) {
+        if (# Mass-storage controller.  Definitely important.
+            $class eq "08" ||
+
+            # Keyboard.  Needed if we want to use the
+            # keyboard when things go wrong in the initrd.
+            ($class eq "03" && $protocol eq "01")
+            )
+        {
+            push @initrdKernelModules, $module;
+        }
+    }
+}
+
+foreach my $path (glob "/sys/bus/usb/devices/*") {
+    if (-e "$path/bInterfaceClass") {
+        usbCheck $path;
+    }
+}
+
+
+
+# Generate the configuration file.
+
+sub removeDups {
+    my %seen;
+    my @res = ();
+    foreach my $s (@_) {
+        if (!defined $seen{$s}) {
+            $seen{$s} = "";
+            push @res, $s;
+        }
+    }
+    return @res;
+}
+
+sub toNixExpr {
+    my $res = "";
+    foreach my $s (@_) {
+        $res .= " \"$s\"";
+    }
+    return $res;
+}
+
+my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
+my $kernelModules = toNixExpr(removeDups @kernelModules);
+ 
+
+print <<EOF ;
+# This is a generated file.  Do not modify!
+# Make changes to /etc/nixos/configuration.nix instead.
+{
+  boot = {
+    initrd = {
+      extraKernelModules = [ $initrdKernelModules ];
+    };
+    kernelModules = [ $kernelModules ];
+  };
+
+  nix = {
+    maxJobs = $cpus;
+  };
+}
+EOF