kernel – passing module parameters

With normal programs that allow you pass parameters on there command line, for example

printoutmyname genux

where the program is called printoutmyname and the first parameter is genux (it is normal that the first parameter [0] is actually the program name and the second parameter [1] is the parameter that is passed)

Well in Linux kernel (where here is a example on how to compile the kernel for a ubuntu based setup) you can pass parameters to the modules that are getting loaded. One module would be your graphics card, in my case a nvidia graphics card.

To find out what parameters can be passed to the graphics card you will have to find the kernel module file (filename.ko, where the ko is the kernel object file), so to search for the nvidia.ko in my case I did

locate nvidia.ko

and then changed to that directory and did a module information on it

cd /lib/modules/2.6.31-17-generic/updates/dkms/
ls
nvidia.ko  vboxdrv.ko  vboxnetadp.ko  vboxnetflt.ko

and doing a module information on it you call the modinfo on the kernel object file as

modinfo nvidia.ko
</pre
 
my output was
 
<pre lang="bash">
filename:       nvidia.ko
license:        NVIDIA
alias:          char-major-195-*
alias:          pci:v000010DEd*sv*sd*bc03sc02i00*
alias:          pci:v000010DEd*sv*sd*bc03sc00i00*
depends:
vermagic:       2.6.31-17-generic SMP mod_unload modversions
parm:           NVreg_EnableVia4x:int
parm:           NVreg_EnableALiAGP:int
parm:           NVreg_ReqAGPRate:int
parm:           NVreg_EnableAGPSBA:int
parm:           NVreg_EnableAGPFW:int
parm:           NVreg_Mobile:int
parm:           NVreg_ResmanDebugLevel:int
parm:           NVreg_RmLogonRC:int
parm:           NVreg_ModifyDeviceFiles:int
parm:           NVreg_DeviceFileUID:int
parm:           NVreg_DeviceFileGID:int
parm:           NVreg_DeviceFileMode:int
parm:           NVreg_RemapLimit:int
parm:           NVreg_UpdateMemoryTypes:int
parm:           NVreg_UseVBios:int
parm:           NVreg_RMEdgeIntrCheck:int
parm:           NVreg_UsePageAttributeTable:int
parm:           NVreg_EnableMSI:int
parm:           NVreg_MapRegistersEarly:int
parm:           NVreg_RmNvclkIdleGraphics:int
parm:           NVreg_RegistryDwords:charp
parm:           NVreg_NvAGP:int

where the parm: is a parameter to pass to the module on load (insmod, or loaded via the kernel at boot time which you can force to load via the /etc/modules file and the parameters can be placed in the /etc/modprobe.d directory).

for example to load the nvidia module with a parameter NVreg_NvAGP you would do something like

insmod nvidia.ko NVreg_NvAGP=1

and the passing value is 1 to the NVreg_NvAGP parameter

BAR 15 – BAR 1 – no parent – nvidia graphics card does not work

I have come up with a fix for the problem that I was having regarding upgrading my 2GB of RAM to 4GB of RAM, when the nvidia was trying to place its memory request into the new system RAM place, as described in more detail here.

This was the error that I was getting, where the BAR 1 for pci 0000:01:00.0 means the nvidia geforce 7600 256MB graphics card.

[    0.397452] pci 0000:00:01.0: BAR 15: address space collision on of bridge [0xb0000000-0xbfffffff]
[    0.397452] pci 0000:00:01.0: BAR 15: cant allocate resource start :0xb0000000-0xbfffffff
[    0.397452] pci 0000:01:00.0: BAR 1: no parent found for of device [0xb0000000-0xbfffffff]

Also the problem with trying to apply the nvnews fix, which meant just blocking out the 0xc0000000-0xd0000000 range was that there was other devices using that and thus they was gaining that memory range before the nvidia could try to access it. What I have done is to hard code (shall try and do a better fix next), so that if anything tries to gain the memory resource 0xc0000000-0xcfffffff it will block the request and they will re-assign the memory in a later process (great linux kernel there 🙂 ). Then if there is a request for the ranges 0xb0000000 – 0xbfffffff (which is where the ACER BIOS tries to say to put the memory for the nvidia graphics card), move that to the 0xc0000000-0xcfffffff. I have placed at the bottom how the memory is organized before and after the update, where the pci devices that was in the 0xc0 -0xcf ranges are now placed further down in the memory allocation table.

So what I have done is to alter the linux-kernel-source-code /arch/x86/pci/i386.c file, by adding into the function pcibios_allocate_bus_resources come code. I have included the full code for the function below and also just the bit that I have updated further down, it is the bit just after the /* Ian Porter */ 🙂

static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
{                                                                            
        struct pci_bus *bus;                                                 
        struct pci_dev *dev;                                                 
        int idx;                                                             
        struct resource *r;                                                  
 
        /* Depth-First Search on bus tree */
        list_for_each_entry(bus, bus_list, node) {
                if ((dev = bus->self)) {          
                        for (idx = PCI_BRIDGE_RESOURCES;
                            idx < PCI_NUM_RESOURCES; idx++) {
                                r = &dev->resource[idx];     
 
 
/*
Ian Porter added, to test for the nvidia problem
 
[0xb0000000-0xbfffffff] is where the BIOS is telling nvidia to get the memory,
but with 4GB this is where the system memory is.                              
 
a better way of doing this, would be to run the BIOS find memory process twice
and then if no resources can gain memory, e.g. nvidia in this case, flag it for the
second run to then give that the starting area and re-do the rest of them, because 
mainly it is the graphics card that needs the most memory..e.g. 256-512 etc.       
*/                                                                                 
                                if ((r->start >= 0xc0000000) && (r->end <= 0xcfffffff)) {
                                        dev_info(&dev->dev,                              
                                                 " not allocating resource 0xc - 0xcf %pR\n",
                                                 r);                                         
                                        /*                                                   
                                                stop any resources gaining the 0xc0000000 - 0xcfffffff
                                                region, the linux kernel will re-place them.          
                                        */                                                            
                                        r->flags = 0;                                                 
                                }                                                                     
 
                                /* where the nvidia is going and replace in the above region */
                                if ((r->start == 0xb0000000) && (r->end == 0xbfffffff)) {      
                                        r->start = 0xc0000000;                                 
                                        r->end = 0xcfffffff;                                   
                                }                                                              
/* stop insert */
 
                                if (!r->flags)
                                        continue;
                                if (!r->start || 
                                    pci_claim_resource(dev, idx) < 0) {
                                        dev_warn(&dev->dev, "BAR %d: can't allocate resource\n", idx);
                                        /*                                                            
                                         * Something is wrong with the region.                        
                                         * Invalidate the resource to prevent                         
                                         * child resource allocations in this                         
                                         * range.                                                     
                                         */                                                           
                                        r->flags = 0;                                                 
                                }                                                                     
                        }                                                                             
                }                                                                                     
                pcibios_allocate_bus_resources(&bus->children);                                       
        }                                                                                             
}

Basically just place this code

/*
Ian Porter added, to test for the nvidia problem
 
[0xb0000000-0xbfffffff] is where the BIOS is telling nvidia to get the memory,
but with 4GB this is where the system memory is.                              
 
a better way of doing this, would be to run the BIOS find memory process twice
and then if no resources can gain memory, e.g. nvidia in this case, flag it for the
second run to then give that the starting area and re-do the rest of them, because 
mainly it is the graphics card that needs the most memory..e.g. 256-512 etc.       
*/                                                                                 
                                if ((r->start >= 0xc0000000) && (r->end <= 0xcfffffff)) {
                                        dev_info(&dev->dev,                              
                                                 " not allocating resource 0xc - 0xcf %pR\n",
                                                 r);                                         
                                        /*                                                   
                                                stop any resources gaining the 0xc0000000 - 0xcfffffff
                                                region, the linux kernel will re-place them.          
                                        */                                                            
                                        r->flags = 0;                                                 
                                }                                                                     
 
                                /* where the nvidia is going and replace in the above region */
                                if ((r->start == 0xb0000000) && (r->end == 0xbfffffff)) {      
                                        r->start = 0xc0000000;                                 
                                        r->end = 0xcfffffff;                                   
                                }

after the

  r = &dev->resource[idx];

in the for loop

compile up the kernel as on this post, the basics are

cd /usr/src/
apt-get install fakeroot kernel-wedge build-essential makedumpfile
 
apt-get build-dep linux
 
apt-get build-dep linux-image-$(uname -r)
apt-get source linux-image-$(uname -r)
 
debian/rules updateconfigs
 
cd debian.master/scripts/misc 
chmod a+x *
cd -
debian/rules updateconfigs

make the changes as described in the file arch/x86/pci/i386.c as above, and then

fakeroot debian/rules clean
CONCURRENCY_LEVEL=2 AUTOBUILD=1 NOEXTRAS=1 fakeroot debian/rules binary-generic

this will create a linux image and headers debian file, after a long wait in the /usr/src directory there will be couple of deb files (Of course change the files names for the header and image that you may have)

cd ..
dpkg -i  linux-headers-2.6.31-17-generic_2.6.31-17.54_amd64.deb
dpkg -i linux-image-2.6.31-17-generic_2.6.31-17.54_amd64.deb

To stop the aptitude from trying to update the linux-image back to the stock one I just did (again change to the image and headers that you have)

aptitude hold linux-image-2.6.31-17-generic_2.6.31-17.54_amd64.deb 
aptitude hold  linux-headers-2.6.31-17-generic_2.6.31-17.54_amd64.deb

Also had to do

echo linux-headers-2.6.31-17-generic hold | dpkg --set-selections
echo linux-image-2.6.31-17-generic hold | dpkg --set-selections

To stop the apt-get upgrade/update as well.

IOMEM of a none working 4GB graphics card, if you note that there is not enough chunck of memory to house the nvidia 256MB memory grab, but there is space enough if the items between the 0xc0000000 – 0xcfffffff are moved about then there is enough space.

00000000-00000fff : System RAM         
00001000-00005fff : reserved           
00006000-0009b3ff : System RAM         
0009b400-0009ffff : reserved           
000dc000-000dffff : reserved           
000e4000-000fffff : reserved           
00100000-bfe8ffff : System RAM         
  01000000-01530dd8 : Kernel code      
  01530dd9-018236af : Kernel data      
  018d5000-019e4ccb : Kernel bss       
  02000000-09ffffff : Crash kernel     
bfe90000-bfe99fff : ACPI Non-volatile Storage
bfe9a000-bfffffff : reserved                 
c0000000-c1ffffff : PCI Bus 0000:03          
c2000000-c3ffffff : PCI Bus 0000:05          
c4000000-c5ffffff : PCI Bus 0000:02          
  c4000000-c401ffff : 0000:02:00.0           
c6000000-c7ffffff : PCI Bus 0000:07          
c8000000-c9ffffff : PCI Bus 0000:03          
ca000000-cbffffff : PCI Bus 0000:05          
cc000000-cdffffff : PCI Bus 0000:02          
  cc000000-cc003fff : 0000:02:00.0           
    cc000000-cc003fff : sky2                 
ce000000-cfffffff : PCI Bus 0000:07          
  ce000000-ce000fff : 0000:07:00.0           
    ce000000-ce000fff : iwl3945              
d0000000-d1ffffff : PCI Bus 0000:01
  d0000000-d0ffffff : 0000:01:00.0
  d1000000-d1ffffff : 0000:01:00.0
d2000000-d20fffff : PCI Bus 0000:09
  d2000000-d2003fff : 0000:09:06.1
  d2004000-d2004fff : 0000:09:06.2
    d2004000-d2004fff : tifm_7xx1
  d2005000-d20057ff : 0000:09:04.0
    d2005000-d20057ff : saa7133[0]
  d2005800-d2005fff : 0000:09:06.1
    d2005800-d2005fff : ohci1394
  d2006000-d20060ff : 0000:09:06.3
    d2006000-d20060ff : mmc0
  d2007000-d2007fff : 0000:09:06.0
    d2007000-d2007fff : yenta_socket
d2300000-d2303fff : 0000:00:1b.0
  d2300000-d2303fff : ICH HD audio
d2304000-d23043ff : 0000:00:1d.7
  d2304000-d23043ff : ehci_hcd
d2304400-d23047ff : 0000:00:1f.2
  d2304400-d23047ff : ahci
d4000000-d7ffffff : PCI Bus 0000:09
  d4000000-d7ffffff : PCI CardBus 0000:0a
d8000000-dbffffff : PCI CardBus 0000:0a
e0000000-efffffff : PCI MMCONFIG 0 [00-ff]
  e0000000-efffffff : reserved
    e0000000-efffffff : pnp 00:01
fec00000-fec0ffff : reserved
  fec00000-fec00fff : IOAPIC 0
fed00000-fed003ff : HPET 0
  fed00000-fed003ff : reserved
fed14000-fed19fff : reserved
  fed14000-fed17fff : pnp 00:01
  fed18000-fed18fff : pnp 00:01
  fed19000-fed19fff : pnp 00:01
fed1c000-fed8ffff : reserved
  fed1c000-fed1ffff : pnp 00:01
  fed20000-fed3ffff : pnp 00:01
  fed45000-fed8ffff : pnp 00:01
fee00000-fee00fff : Local APIC
  fee00000-fee00fff : reserved
ff000000-ffffffff : reserved

Working IOMEM 4GB graphics nvidia geforce 7600 256MB card, the items that was in the 0xc0000000 – 0xcfffffff ranges are now placed further down in the memory allocations, if you look for sky2 , iwl3945 , which are kinder needed for the wireless capabilities of the laptop.

00000000-00000fff : System RAM               
00001000-00005fff : reserved                 
00006000-0009b3ff : System RAM               
0009b400-0009ffff : reserved                 
000dc000-000dffff : reserved                 
000e4000-000fffff : reserved                 
00100000-bfe8ffff : System RAM               
  01000000-01530f79 : Kernel code            
  01530f7a-018216ef : Kernel data            
  018d3000-019e2ccb : Kernel bss             
  02000000-09ffffff : Crash kernel           
bfe90000-bfe99fff : ACPI Non-volatile Storage
bfe9a000-bfffffff : reserved                 
c0000000-cfffffff : PCI Bus 0000:01          
  c0000000-cfffffff : 0000:01:00.0           
d0000000-d1ffffff : PCI Bus 0000:01          
  d0000000-d0ffffff : 0000:01:00.0           
  d1000000-d1ffffff : 0000:01:00.0           
    d1000000-d1ffffff : nvidia               
d2000000-d20fffff : PCI Bus 0000:09          
  d2000000-d2003fff : 0000:09:06.1           
  d2004000-d2004fff : 0000:09:06.2           
    d2004000-d2004fff : tifm_7xx1            
  d2005000-d20057ff : 0000:09:04.0           
    d2005000-d20057ff : saa7133[0]
  d2005800-d2005fff : 0000:09:06.1
    d2005800-d2005fff : ohci1394
  d2006000-d20060ff : 0000:09:06.3
    d2006000-d20060ff : mmc0
  d2007000-d2007fff : 0000:09:06.0
    d2007000-d2007fff : yenta_socket
d2100000-d21fffff : PCI Bus 0000:02
  d2100000-d2103fff : 0000:02:00.0
    d2100000-d2103fff : sky2
d2200000-d22fffff : PCI Bus 0000:02
  d2200000-d221ffff : 0000:02:00.0
d2300000-d2303fff : 0000:00:1b.0
  d2300000-d2303fff : ICH HD audio
d2304000-d23043ff : 0000:00:1d.7
  d2304000-d23043ff : ehci_hcd
d2304400-d23047ff : 0000:00:1f.2
  d2304400-d23047ff : ahci
d2400000-d24fffff : PCI Bus 0000:07
  d2400000-d2400fff : 0000:07:00.0
    d2400000-d2400fff : iwl3945
d4000000-d7ffffff : PCI Bus 0000:09
  d4000000-d7ffffff : PCI CardBus 0000:0a
d8000000-dbffffff : PCI CardBus 0000:0a
e0000000-efffffff : PCI MMCONFIG 0 [00-ff]
  e0000000-efffffff : reserved
    e0000000-efffffff : pnp 00:01
fec00000-fec0ffff : reserved
  fec00000-fec00fff : IOAPIC 0
fed00000-fed003ff : HPET 0
  fed00000-fed003ff : reserved
fed14000-fed19fff : reserved
  fed14000-fed17fff : pnp 00:01
  fed18000-fed18fff : pnp 00:01
  fed19000-fed19fff : pnp 00:01
fed1c000-fed8ffff : reserved
  fed1c000-fed1ffff : pnp 00:01
  fed20000-fed3ffff : pnp 00:01
  fed45000-fed8ffff : pnp 00:01
fee00000-fee00fff : Local APIC
  fee00000-fee00fff : reserved
ff000000-ffffffff : reserved

hope this post helps other people to get around the nvidia laptop memory grab, hopefully I am going to write a pci kernel update so that it does not have to block out a set part of memory.