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.
Responses
pit
At me it is impossible to start NDIS (complains of absence GPLUS.bin) prompt that to me to make
pit
At me DWL-g520 +
Anonymous
Thank you :)
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.
dannyman
Eric McConkey has mirrored this information, with some addional notes, at: http://www.ericmcconkey.com/index.php?cmd=newsdetail&extras=12
ColtonCat
Very nice indeed…!!! Thanks for the Howto
Andrew Purcell
Thanks man, you’re a lifesaver.
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.
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 Ü
Fuad
can it work on modem driver?
JackBauer
Hi,
Thanks a lot for your helpfull instructions.
It’s a very very very clear topic!!
Thanks again
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
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…
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…
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?
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!
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!
Moods' Blog
Win drivers under freebsd Sagem SA XG703 USB 802.11g
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
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.
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!
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. […]
sgh
Big Thanks!!! from Russia :)
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?
Bens
Great! Thanks from Holland to:)
kevin
so anyone had any luck doing this on FreeBSD AMD64?
im D/L’in AMD64 right now let cha know how it goes
sarelo
Step 6: Compile, Install
Basically:
make && make install
don’t work ;/ (don’t work how to make install)
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,
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?
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
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.
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!
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.
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 […]
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.
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
Tiny Print:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>