dannyman.toldme.com


FreeBSD, Technical

HOWTO: NDISulate Windows Drivers on FreeBSD

This is the second time I am going to use NDIS to allow FreeBSD to load the Windows drivers for a Dell laptop to access the built-in wireless. As this is my second time, it is good to make my own crib sheet of what I have to do, so I can do it even quicker next time, and because you, the reader, might find yourself here thanks to Google.

In both cases that I have done this I have been starting with FreeBSD 5.3. According to this crib sheet, you need to be fairly current with 5.x to do this. That crib sheet is also my main source of reference.

If you have already done this to your system and find yourself having to re-do NDIS after an upgrade, you may find my “rendis” script handy.

If you have already done this to your system, and are tracking -STABLE I have read that you no longer have to follow these steps, but merely run:
ndisgen

Step 1: Install NDIS code

cd /sys/modules/ndis && make && make install

Step 2: Figure out what hardware you have to support

This can be annoying . . . vendors ship different components in their machines, along with driver disks with all the possible variants of drivers, so you have to find the right driver. Unless you’re a big hardware weenie, you’re not sure, and pulling the right driver from the vendor can be hard.

If yours is a PCI device, you can ask pciconf to list what is on the system, and collate it with a vendor/device information database:

pciconf -lv

And here I see:

none6@pci2:4:0: class=0x028000 card=0x00031028 chip=0x432014e4 rev=0x03 hdr=0x00
    vendor   = 'Broadcom Corporation'
    device   = 'BCM4306 802.11b/g Wireless LAN Controller'
    class    = network

Step 3: Go Get the Win2K/XP Driver

You have to pull this off the CDROM or a web site yourself. Bonus points when the driver is packaged in a self-extracting archive, then you have to borrow a Windows machine to get the .sys and .inf files. Joy!

In this case, Dell re-brands the Broadcom driver as a Dell driver, so I download the “Dell _Wireless (US) WLAN Network Adapter Card” from their web site, extract the files on my Windows box, and select the bcmwl5.inf and bcmwl5.sys

Step 4: Copy those Drivers to /sys/modules/if_ndis

# ls *.inf *.sys
bcmwl5.inf      bcmwl5.sys      bcmwl5a.inf     bcmwlntp.sys
# cp bcmwl5.* /sys/modules/if_ndis
# ls /sys/modules/if_ndis
Makefile        bcmwl5.inf      bcmwl5.sys
# cd /sys/modules/if_ndis

Step 5: Magic

Take a deep breath, stretch your arms, think a happy though, and:

# ndiscvt -i bcmwl5.inf -s bcmwl5.sys -o ndis_driver_data.h
ndiscvt: line 13: e: syntax error.
ÿþ[#

Okay, don’t panic! I have seen this before. The ndiscvt works on ASCII files, but many a crafty driver has been distributing stuff in Unicode. If I look at bcmwl5.inf, I see:

# hd bcmwl5.inf | head -3
00000000  ff fe 3b 00 3b 00 0d 00  0a 00 3b 00 3b 00 20 00  |..;.;.....;.;. .|
00000010  62 00 63 00 6d 00 77 00  6c 00 35 00 2e 00 69 00  |b.c.m.w.l.5...i.|
00000020  6e 00 66 00 0d 00 0a 00  3b 00 3b 00 0d 00 0a 00  |n.f.....;.;.....|

For your edification, if a file looks like null-padded ASCII characters, then it is probably UTF-16.

# iconv -c -f utf-16 -t ascii bcmwl5.inf > bcmwl5.inf.ascii
# head -3 bcmwl5.inf.ascii
;;
;; bcmwl5.inf
;;
# ndiscvt -i bcmwl5.inf.ascii  -s bcmwl5.sys -o ndis_driver_data.h

Well, that was easy.

Step 6: Compile, Install

Basically:

make && make install

Load the module:

kldload ndis
kldload if_ndis

And, see if you have an Ethernet device:

# ifconfig ndis0
ndis0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
        ether ff:ff:ff:ff:ff:ff
        media: IEEE 802.11 Wireless Ethernet autoselect
        status: no carrier
        ssid ""
        channel -1 authmode OPEN powersavemode OFF powersavesleep 100
        rtsthreshold 2312 protmode CTS
        wepmode OFF weptxkey 1

(You shouldn’t ever have that as a MAC address, unless you’re blogging sensitive data to the Internet. ;)

Loading NDIS at Boot

Once you are happy with your NDIS, add a line like this to /boot/loader.conf, which will cause the kernel to load your new module at boot time:

if_ndis_load="YES"

At this point, you’re ready to get back to your FreeBSD Handbook if you need further information.

Read More

Next:
Previous:
Categories: FreeBSD, Technical
Possibly-Related Posts

Responses

February 16th, 2005

pit

At me it is impossible to start NDIS (complains of absence GPLUS.bin) prompt that to me to make

February 16th, 2005

pit

At me DWL-g520 +

February 17th, 2005

Anonymous

Thank you :)

March 22nd, 2005

Jeff Long

Thanks a ton, I’ve used this twice now. Once on an Emachines M5312 Laptop / Broadcom Wireless 54g, and just now on my desktop with a Linksys WMP11.

April 13th, 2005

dannyman

Eric McConkey has mirrored this information, with some addional notes, at: http://www.ericmcconkey.com/index.php?cmd=newsdetail&extras=12

May 15th, 2005

ColtonCat

Very nice indeed…!!! Thanks for the Howto

June 12th, 2005

Andrew Purcell

Thanks man, you’re a lifesaver.

June 29th, 2005

Adam

I am always grateful for those who work through problems, find solutions, and then share them with the world. One thing I’ll post for those who may have a Motorola 802.11G PCMCIA card is that do NOT use the standard Broadcom drivers floating around that work in most cases, only the drivers from Motorola (bcmwl5.inf and bcmwl5.sys) that are packed in an *.exe file work.

July 15th, 2005

Jamie

Hi, thanks for this info.Ü Question: I’m trying to install the linksys WMP11 on freebsd 4.3, but I don’t think 4.3 supports NDIS. So there’s really *no* way I can install it unless I upgrade the OS? Thanks Ü

August 1st, 2005

Fuad

can it work on modem driver?

August 20th, 2005

JackBauer

Hi,
Thanks a lot for your helpfull instructions.
It’s a very very very clear topic!!
Thanks again

September 1st, 2005

Lyubich, M

Great HOWTO! Thanks.

I have an additional point. I used wine from FreeBSD port collection to run the selfextracting archive (*.exe) and to extract the valuable (*.inf and *.sys) files.

Regards, ML

October 28th, 2005

Alexandre Drummond

I can load the ndis driver (NetGear WG311v2) but it’s impossible to set the ssid. When I try to set the ssid (ifconfig ndis0 ssid mynetwork channel 6) it runs but doesn’t output anything and when I check if it worked, its status remains “no carrier”, its ssid is still “” and channel -1…

November 9th, 2005

Paul Bransford

Doesn’t work for me, i have a broadcom 802.11b/g (same driver file names as your example even).

ifconfig ndis0 reports that the interface doesn’t exist…

November 28th, 2005

João Henrique

In my old FreeBSD box running 5.4, the wireless network worked fine. In my actual box (6.0) does not exist ndis0 interface, just like Paul Bransford case.
Tips?

December 6th, 2005

João Henrique

SOLVED: just follow the direction found in http://www.freebsd.org/cgi/man.cgi?query=ndisgen&sektion=8&manpath=FreeBSD+6.0-RELEASE

Good luck!

February 24th, 2006

Ryan

Thanks a lot! I found info on how to NDISulate, but I had that same problem with the UTF-16 (they try to be tricky, don’t they?) Your info was all I needed. Thanks again!

June 16th, 2006

Moods' Blog

Win drivers under freebsd Sagem SA XG703 USB 802.11g

July 15th, 2006

Ernesto Quiñones

Hello I run the options from the guide

1.cd /sys/modules/ndis && make && make install OK

2.pciconf -lv OK
none1@pci0:12:0: class=0x028000 card=0x041814e4 chip=0x432014e4 rev=0x03 hdr=0x00
vendor = ‘Broadcom Corporation’
device = ‘BCM4306 802.11b/g Wireless LAN Controller’
class = network

3.cp bcmwl5.* /sys/modules/if_ndis OK

4.# ndiscvt -i bcmwl5.inf -s bcmwl5.sys -o ndis_driver_data.h
ndiscvt: line 13: e: syntax error.
ÿþ[root@myhost# OK

5. # hd bcmwl5.inf | head -3 OK
00000000 ff fe 3b 00 3b 00 0d 00 0a 00 3b 00 3b 00 20 00 |..;.;…..;.;. .|
00000010 62 00 63 00 6d 00 77 00 6c 00 35 00 2e 00 69 00 |b.c.m.w.l.5…i.|
00000020 6e 00 66 00 0d 00 0a 00 3b 00 3b 00 0d 00 0a 00 |n.f…..;.;…..|

6. # iconv -c -f utf-16 -t ascii bcmwl5.inf > bcmwl5.inf.ascii OK

7. # head -3 bcmwl5.inf.ascii OK
;;
;; bcmwl5.inf
;;

BUT!!!
8. root@depeche# ndiscvt -i bcmwl5.inf.ascii -s bcmwl5.sys -o ndis_driver_data.h
ndiscvt: line 1902: : syntax error.

any body can help me please?

thx

July 26th, 2006

Marlon Mark

everything seems to go ok.. but when i run kloads… i get this

kifkroker# kldload ndis
kldload: can’t load ndis: File exists
kifkroker# kldload if_ndis
kldload: can’t load if_ndis: File exists

thanks for your help in advance.

August 22nd, 2006

Rob Jerina

I tried this solution:

http://www.freebsd.org/cgi/man.cgi?query=ndisgen&sektion=8&manpath=FreeBSD+6.0-RELEASE

I get a page fault and my laptop reboots!

October 10th, 2006

Sander’s Weblog » FreeBSD and Wireless PCI Card

[…] Initially, I came away with a LinkSys WMP11 card that would cost me, after two rebates, the grand sum of five dollars. I had googled for this product and found out it is based on the well-supported Prism chipset, so I took one home. However, the card I had bought turned out to be a new revision, with a completely different chipset that the FreeBSD developers had never heard of! Thanks Linksys for springing that on the unsuspecting public. Of course there are Windows drivers, so the unsuspecting public still has something to play with. As, it turned out, did I. I turned to the NDIS wrapper support and found out that this only came with FreeBSD 5: time to upgrade the box from 4-STABLE. After a fresh new install (the only thing building world did for me was make every program I started dump core… boy was I glad that I had backed up my home directory before I started on this track), I got the NDIS driver to work (great hints by Dannyman), but unfortunately it did not support WEP. Why do we care about WEP? Isn’t it completely uncool to rely on WEP these days? Actually, it is in a way. In the same way that the lock on a bathroom stall door prompts most people to try the other stall, I assume the 1337 H@x0R is going to hook up to the unencrypted network first and I can see up to six open networks from my second bedroom. […]

October 26th, 2006

sgh

Big Thanks!!! from Russia :)

November 20th, 2006

etenv

João Henrique: i’m facing the same problem here. Everything goes well until the ifconfig ndis0 up, where he says, that the interface ndis0 does not exist. How did you fixed it?? On that link that you’ve posted is only the man page but no instructions…

Can somebody else help me with that?

December 1st, 2006

Bens

Great! Thanks from Holland to:)

December 16th, 2006

kevin

so anyone had any luck doing this on FreeBSD AMD64?

im D/L’in AMD64 right now let cha know how it goes

December 31st, 2006

sarelo

Step 6: Compile, Install

Basically:

make && make install

don’t work ;/ (don’t work how to make install)

January 27th, 2007

Mario Castelao

To everybody having problems with:
#kldload ndis
kldload: can’t load ndis: File exists
#kldload if_ndis
kldload: can’t load if_ndis: File exists
or:
#ifconfig ndis0
ndis0 does not exist

The solution was posted by João Henrique but if you want a more detailed explanation here you go:
start by using ndisgen, its synopsis is:

ndisgen [/path/to/INF /path/to/SYS]

therefore:
#cd /sys/modules/if_ndis/
#ndisgen bcmwl5.inf bcmwl5.sys
and then follow the “wizard”, (basically pressing “enter,return” a few times…) and generate the following bcmwl5_sys.ko , after this you can either load the module by typing the command:
#kldload /sys/modules/if_ndis/bcmwl5_sys.ko
or create a link to the module in the /boot/kernel and then load it:
#ln /boot/kernel/bcmwl5.ko /sys/modules/if_ndis/bcmwl5_sys.ko
#kldload bcmwl5_sys.ko
or copy it into /boot/kernel and then load it:
#cp /sys/modules/if_ndis/bcmwl5_sys.ko /boot/kernel/bcmwl5.ko
#kldload bcmwl5_sys.ko
after all of this you can simply add in your /boot/loader.conf the following line to load the module on boot:
bcmwl5_sys_load=”YES”

Hope it helped,

March 16th, 2007

randell meyer

ok so I am running a realtek 8185 wireless and a Emaechines N10 laptop I can run all of this but when I run kldload I get a falt Trap 12 and a reboot any tips?

May 5th, 2007

br0(rus)

I found solution about trap 12. First you need bcmwl5.inf with version is 3.xxx not 4. I have 3.140, from HP site here: http://h20000.www2.hp.com/bizsupport/site/search/r4_0/jsp/search.jsp?lang=en&cc=us&tx=Broadcom+Wireless+LAN+Driver&sc=1&nh=10&rf=0&lkc=1&lk=1&sts=1
Also you will need to patch file nsubr_ntoskrnl.c – of ndis module, you can find here /usr/src/sys/compat/ndis/

Here is patch:

dangerb0x# cat pt
diff -u -r1.87 subr_ntoskrnl.c
— sys/compat/ndis/subr_ntoskrnl.c 16 May 2006 14:37:57 -0000 1.87
+++ sys/compat/ndis/subr_ntoskrnl.c 26 Nov 2006 18:19:29 -0000
@@ -197,6 +197,11 @@
static uint32_t InterlockedIncrement(volatile uint32_t *);
static uint32_t InterlockedDecrement(volatile uint32_t *);
static void ExInterlockedAddLargeStatistic(uint64_t *, uint32_t);
+static void *MmAllocateContiguousMemory(uint32_t, uint64_t);
+static void *MmAllocateContiguousMemorySpecifyCache(uint32_t,
+ uint64_t, uint64_t, uint64_t, uint32_t);
+static void MmFreeContiguousMemory(void *);
+static void MmFreeContiguousMemorySpecifyCache(void *, uint32_t, uint32_t);
static uint32_t MmSizeOfMdl(void *, size_t);
static void *MmMapLockedPages(mdl *, uint8_t);
static void *MmMapLockedPagesSpecifyCache(mdl *,
@@ -232,11 +237,14 @@
uint32_t, void *);
static uint32_t WmiTraceMessage(uint64_t, uint32_t, void *, uint16_t, …);
static uint32_t IoWMIRegistrationControl(device_object *, uint32_t);
-static void *ntoskrnl_memset(void *, int, size_t);
+#ifdef MEMCHR
+static void *ntoskrnl_memchr(const void *, unsigned char, size_t);
+#endif
static void *ntoskrnl_memmove(void *, void *, size_t);
+static void *ntoskrnl_memset(void *, int, size_t);
static char *ntoskrnl_strstr(char *, char *);
-static int ntoskrnl_toupper(int);
static int ntoskrnl_tolower(int);
+static int ntoskrnl_toupper(int);
static funcptr ntoskrnl_findwrap(funcptr);
static uint32_t DbgPrint(char *, …);
static void DbgBreakPoint(void);
@@ -433,6 +441,34 @@
return(dst);
}

+#ifdef MEMCHR
+
+/*
+ * /usr/src/sys/modules/ndis/../../compat/ndis/subr_ntoskrnl.c: In function `ntoskrnl_memchr’:
+ * /usr/src/sys/modules/ndis/../../compat/ndis/subr_ntoskrnl.c:463: warning: cast discards qualifiers from pointer target type
+ * *** Error code 1
+ */
+
+/* copied from src/lib/libc/string/memchr.c */
+
+static void *
+ntoskrnl_memchr(buf, ch, len)
+ const void *buf;
+ unsigned char ch;
+ size_t len;
+{
+ if (len != 0) {
+ const unsigned char *p = buf;
+
+ do {
+ if (*p++ == ch)
+ return ((void *)(p – 1)); /* error occurs here */
+ } while (–len != 0);
+ }
+ return (NULL);
+}
+#endif
+
static char *
ntoskrnl_strstr(s, find)
char *s, *find;
@@ -2471,6 +2507,53 @@
return;
}

+static void *
+MmAllocateContiguousMemory(size, highest)
+ uint32_t size; /* Specifies the number of bytes to allocate */
+ uint64_t highest; /* Specifies the highest valid physical address that the driver can use. */
+{
+ void *addr;
+ size_t pagelength = ((size + PAGE_SIZE – 1) / PAGE_SIZE) * PAGE_SIZE;
+
+ addr = ExAllocatePoolWithTag(NonPagedPool, pagelength, 0);
+
+ return(addr);
+}
+
+static void *
+MmAllocateContiguousMemorySpecifyCache(size, lowest, highest, boundary, cachetype)
+ uint32_t size; /* Specifies the number of bytes to allocate */
+ uint64_t lowest; /* Specifies the lowest valid physical address that the driver can use. */
+ uint64_t highest; /* Specifies the highest valid physical address that the driver can use. */
+ uint64_t boundary; /* If nonzero, this value specifies the physical address multiple that */
+ /* the allocated buffer must not cross. */
+ uint32_t cachetype; /* indicates the type of caching allowed for the requested memory */
+{
+ void *addr;
+ size_t pagelength = ((size + PAGE_SIZE -1) / PAGE_SIZE) * PAGE_SIZE;
+
+ addr = ExAllocatePoolWithTag(NonPagedPool, pagelength, 0);
+
+ return(addr);
+}
+
+static void
+MmFreeContiguousMemory(base)
+ void *base; /* Specifies the base address of the buffer to be freed */
+{
+ ExFreePool(base);
+}
+
+static void
+MmFreeContiguousMemorySpecifyCache(base, size, cachetype)
+ void *base; /* Specifies the base address of the buffer to be freed */
+ uint32_t size; /* Specifies the size in bytes of the buffer to be freed. Must match the */
+ /* size requested when the buffer was allocated */
+ uint32_t cachetype; /* Specifies the cache type of the buffer to be freed */
+{
+ ExFreePool(base);
+}
+
static uint32_t
MmSizeOfMdl(vaddr, len)
void *vaddr;
@@ -4144,6 +4227,7 @@
IMPORT_SFUNC(DbgBreakPoint, 0),
IMPORT_CFUNC(strncmp, 0),
IMPORT_CFUNC(strcmp, 0),
+ IMPORT_CFUNC_MAP(stricmp, strcasecmp, 0),
IMPORT_CFUNC(strncpy, 0),
IMPORT_CFUNC(strcpy, 0),
IMPORT_CFUNC(strlen, 0),
@@ -4151,6 +4235,10 @@
IMPORT_CFUNC_MAP(tolower, ntoskrnl_tolower, 0),
IMPORT_CFUNC_MAP(strstr, ntoskrnl_strstr, 0),
IMPORT_CFUNC_MAP(strchr, index, 0),
+ IMPORT_CFUNC_MAP(strrchr, rindex, 0),
+#ifdef MEMCHR
+ IMPORT_CFUNC_MAP(memchr, ntoskrnl_memchr, 0),
+#endif
IMPORT_CFUNC(memcpy, 0),
IMPORT_CFUNC_MAP(memmove, ntoskrnl_memmove, 0),
IMPORT_CFUNC_MAP(memset, ntoskrnl_memset, 0),
@@ -4239,6 +4327,11 @@
IMPORT_FFUNC(ExInterlockedAddLargeStatistic, 2),
IMPORT_SFUNC(IoAllocateMdl, 5),
IMPORT_SFUNC(IoFreeMdl, 1),
+ IMPORT_SFUNC(MmAllocateContiguousMemory, 2),
+ IMPORT_SFUNC(MmAllocateContiguousMemorySpecifyCache, 5),
+ IMPORT_SFUNC(MmFreeContiguousMemory, 1),
+ IMPORT_SFUNC(MmFreeContiguousMemorySpecifyCache, 3),
+ IMPORT_SFUNC_MAP(MmGetPhysicalAddress, pmap_kextract, 1),
IMPORT_SFUNC(MmSizeOfMdl, 1),
IMPORT_SFUNC(MmMapLockedPages, 2),
IMPORT_SFUNC(MmMapLockedPagesSpecifyCache, 6),
———————————————————-
Patching:

dangerb0x# patch

May 12th, 2007

anonymous1

Hello, i am having a problem
First of all, i did the ndisgen /ndisdriver.inf /ndisdriver.sys command
i go through the ndisgen interactive program, it says everything was succesful
but when i go to load my file with kldload ./ndisdriver_sys.ko i get this output
no match for InterlockCompareExchange
no match for KeSetPriorityThread
no match for KeGetCurrentThread
no match for USBD_ParseConfigurationDescriptor
no match for USBD_ParseConfigurationRequest

Can someone tell me how to make sense of that, and what i would need to do, thanks in advance.

June 15th, 2007

NoHup

Hey br0(rus)!

Why not post the patched ko module? I’m having difficulty patching using FreeBSD 6.2 and would love to test your module for the Realtek 8185 via NDIS. Btw, great how to article dannyman. Thanks!

November 2nd, 2007

Grega

hej!

well, i own a Asus WL-138G V2 (bcmwl5) wireless lan card.
Everything looks OK, except theres no ndis in ifconfig (nothing new – only old interfaces).

> kldstat
Id Refs Address Size Name
1 10 0xffffffff80100000 6bf990 kernel
2 2 0xffffffff807c0000 10510 if_ndis.ko
3 3 0xffffffff807d1000 25fe0 ndis.ko
4 1 0xffffffff807f7000 89390 bcmwl5.ko
5 1 0xffffffff977e0000 795 accf_http.ko

I am using Freebsd 6.2 (64bit), but i am not sure windows XP drivers were for 64 bit. Would i get an error if it werent?

Thank you.

November 7th, 2007

Desktop BSD Day 7 - Fooling around ¦ Ruminations on the Digital Realm

[…] step by step tutorial on how to use ndisgen can be found here and here. I haven’t tried it yet, but it looks similar to […]

April 25th, 2008

md20

Found two errors to beware of when using ndisgen -w- FreeBSD 7.0-RELEASE and the HP inf for SP28537A.

The internationalization country structs parsing in ndiscvt misses closing braces breaking the compile on lines 552 and 891 of the generated windrv.h.
You must edit windrv.h to fix this. Afterwards the compilation succeeds without a hitch.

November 5th, 2009

Pablo Sánchez

Greetings.

I followed the how-to quite well, got no problems at all, except for you thing:

The module loads, but no new network interface appears! There are no errors, only the driver is loaded (kldstat shows it) but nothing happens!

FreeBSD 7.2 amd64

The interface is a broadcom.

Comment

Leave a comment . . .

Tiny Print:

  1. For private messages, e-mail me: dannyman@toldme.com.
  2. You must provide an e-mail address.
  3. You can use a bogus e-mail address, but I like to know who you are.
  4. I will not spam you. I will not publish or share your e-mail address.
  5. First-time commenters will be held for review.
  6. You can use these HTML tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>