Hi there, I'm trying to solve a long-standing problem with installation of CentOS & Fedora on our nForce-430-based motherboards. The forcedeth kernel module has been pretty fast-moving over the last few kernels and to support our current boards, we need a really fresh version which is generally only found in 2.6.19 or 2.6.20. nVidia backport these drivers to earlier kernels here: http://www.nvidia.com/object/linux_nforce_1.21.html Since we can only perform network network installs, I am trying to work out a general way of retro-fitting the lastest nForce drivers into a given Fedora Core or CentOS install, and I understand the anaconda loader program is the key to this. Unfortunately "use a newer distro" isn't an option in a few cases where customers want a specific Fedora version for support of some random commercial software - right now I am struggling to get FC5 working, but it would be nice if this would fix Centos3/4 which are popularly requested as well. Also despite FC5 being listed as being included in nVidia's binaries, they don't provide a driver disc image. They claim that the FC5 driver should support installation at least, and the RPMs are just to bring it bang up to date after installation. This isn't true on our newest motherboards, it just doesn't seem to spot that the network chip exists. What I've tried so far is to extract the stock pxeboot/initrd.img and the contained modules/modules.cgz files. Then I add in the .ko files from the RPMs that nVidia supply for FC5, then rebuild it all with cpio / gzip. Unfortunately anaconda still says it doesn't have a driver "for the specified installation type", even though I'm 99% sure that the forcedeth.ko file bring up an eth0 (not sure how to launch a shell from the loader to check ;) ). I even tried copying the FC5 x86_64/os directory onto a local drive, then re-launched the network installation and asked it to install off a local hard drive. Again the "no driver found for specified installation type" complaint, even though it offered to load a driver disk off the filesystem on /dev/sda1 which it could clearly access ;-) So from that last problem, I guessed that even if I've put some working driver modules in there, I needed to add some PCI IDs to a list or two. At this point I'm guessing, but I found the modules/pci.ids file and modules/modules.aliases files in the initrd. I've tried altering these to contain information about the nForce drivers (10de:03ef for the network chip, and 10de:03f6 for the SATA chip) but I still see the "no driver found for specified installtion type" for both hard disc and network installs. I've attached my initrd-rebuilding script which I've used for my experiments - can anyone with more expertise on anaconda advise on a next step? Is "slipstreaming" kernel modules possible in this way, or is there a smarter way of going about what I want to do? Thanks, -- Matthew
#!/usr/bin/ruby # # This script rebuilds the given redhat PXE initrd image with modules found # in RPMs. This is useful to update installers with newer kernel modules, # whether the manufacturer has supplied a driver disk or not - as long as # there are some RPMs, you can use them to rebuild and run the installer. # Save some typing # require 'find' require 'fileutils' include FileUtils def xsys(cmd) return if system(cmd) STDERR.print "*** Error running: #{cmd}\n" exit $?.exitstatus end class Dir def self.mkdir_and_work_in(d) mkdir(d) unless File.directory?(d); prev = Dir.pwd; chdir(d); yield; chdir(prev) end end MODULE_PATH = /\.ko$/ # Sanity check on arguments # initrd, initrd_out, *rpms = *ARGV if ARGV.length < 3 || [initrd, *rpms].select { |f| !File.exists?(f) }.length > 0 STDERR.print "Syntax: #{$0} <original initrd.img> <new initrd.img> <rpm 1> [rpm 2 ... ]\n" exit 1 end if File.exists?(initrd_out) STDERR.print "Won't overwrite #{initrd_out}, please move it\n" exit 2 end # Do our work in a temporary directory # Dir.mkdir("/tmp/rebuild.#{$$}") #at_exit { rmtree "/tmp/rebuild.#{$$}" } Dir.chdir("/tmp/rebuild.#{$$}") # Extract initrd # Dir.mkdir_and_work_in("x_initrd") do xsys("gunzip <#{initrd} | cpio -id") end # Extract modules inside initrd, find correct path to put our extra modules # Dir.mkdir_and_work_in("x_modules") do xsys("gunzip <../x_initrd/modules/modules.cgz | cpio -id") end module_path = nil Find.find("x_modules") do |file| next unless MODULE_PATH.match(file) module_path = file.split("/")[0..-2].join("/") break end raise ArgumentError.new("Couldn't find any .ko files in extracted modules.cgz") if module_path.nil? # Extract all the RPMs # rpms.each_with_index do |rpm,idx| Dir.mkdir_and_work_in("x_rpm_#{idx}") do xsys("rpm2cpio #{rpm} | cpio -id") end end # Scout for modules, copy them into our x_modules directory # rpms.length.times do |idx| Find.find("x_rpm_#{idx}") do |file| if MODULE_PATH.match(file) cp(file, module_path) STDERR.print "Copied #{file.split('/')[-1]}\n" end end end # Freshen pci.ids file - probably not necessary, just guessing as it seems # to be the cleanest way to get our nVidia PCI IDs listed. # rm("x_initrd/modules/pci.ids") xsys("wget -q -O x_initrd/modules/pci.ids http://pciids.sourceforge.net/pci.ids") # Add some PCI aliases - total guesswork based on existing entries # File.open("x_initrd/modules/modules.alias", "a") do |fh| fh.print <<__ alias pci:v000010DEd000003efsv*sd*bc*sc*i* forcedeth alias pci:v000010DEd000003f6sv*sd*bc*sc*i* sata_nv __ end # Make a new modules.cgz archive # Dir.mkdir_and_work_in("x_modules") do xsys("find . | cut -f2- -d/ | cpio -o -H newc | gzip >../x_initrd/modules/modules.cgz") end # Make a new initrd.img, move it to the right place # Dir.mkdir_and_work_in("x_initrd") do xsys("find . | cut -f2- -d/ | cpio -o -H newc | gzip >../initrd.img") end mv("initrd.img", initrd_out)