On my MacBook5,2 (Nvidia 9400m video card) if the drivers are installed in Windows, Windows does not boot. Windows is installed in EFI mode, if that matters.

  • What driver version exactly? Did it work before? What precisely happens during boot? (Errors?)
    – slhck
    Nov 9 '13 at 9:50
  • Version from 30 August 2013, the most current version offered by WU.
    – kinokijuf
    Nov 9 '13 at 13:34
  • This is a common problem in Windows 8 and newer on Mac-EFI. (Windows 7 doesn't support Apple-EFI, which is EFI 1.x.) It seems to be due to the Nvidia drivers not working in EFI mode, for two reasons: 1) in EFI mode the setup is different and Apple probably got it wrong, but doesn't care (Mac-EFI is Apples responsibilty!), and 2) Nvidia doesn't bother to produce a workaround. Keep in mind that this setup, Windows 8/8.1/10 in EFI mode, is totally unsupported by Apple though Boot Camp. The Nvidia drivers work well in CSM (BIOS emulation) mode, so Apple's supported way works!
    – luttztfz
    Nov 15 '19 at 14:10

I entered the following into the startup.nsh file of the EFI Shell:

mm 0010003E 1 ;PCI :8
mm 02000004 1 ;PCI :7

Now if there only was a way to set those registers in an EFI variable…

Technical info: While Windows 8 no longer expects an EFI system to have VGA-compatible video, Nvidia drivers apparently still do and crash if they don’t detect it. The above commands are supposed to enable the VGA support in the graphics card.


First of all, @kinokijuf worked perfectly, but it was painful for me to understand what's going on under the hood.

First, this solution worked for me on a Windows 10 with Macbook 5,2 (White/2009)

If you are not used about what is an EFI, I will try my explanation: It's a new way to boot systems, you have a partition on disk for that and a bunch of small EFI programs. This partition usually exists on a Mac/Windows (if installed using EFI option), and you don't see it, unless you mount it.

For mounting on mac:

diskutil list
sudo mkdir /Volumes/efi
sudo mount -t msdos /dev/disk0s1 /Volumes/efi
  • where /dev/disk0s1 is your EFI partition that was listed on first command.


For mounting on Windows, Open prompt with administration privilegies and:

mountvol S: /S

OK and why do I need to know that?

You need to boot your windows but prior to that you need to run this damn commands before, so my recommendation is to first of all INSTALL a better bootloader. I recommend rEFInd, it helped me a lot, and I always use it.

Website: http://www.rodsbooks.com/refind/ Download page: http://www.rodsbooks.com/refind/getting.html Install on Windows or Mac page: http://www.rodsbooks.com/refind/installing.html#windows

Have you done that?

If yes, you currently know that exists an EFI partition and you have already copied all refind files to that place. You can boot and you will see refind taking place of the boot loading process.

You know too that during the process you copied a file called refind.conf, right?

On this file you can configure a "Special Manual Windows Entry", mine is like this:

menuentry "Windows via shell script" {
    icon \EFI\refind\icons\os_win.png
    loader \EFI\tools\Shell_Full.efi
    options "fs0:\EFI\tools\startup.nsh"

If you check you will find out that there's one very similar to this on the conf file actually.

This entry will show up, but for it to work you need another step! I have created on my EFI partition (inside EFI folder) a folder called tools, and inside it I copied a EFI program that I have download from Intel, usually called EFI Shell 2, the file name is Shell_Full.efi.

Here's the source: https://svn.code.sf.net/p/edk2/code/trunk/edk2/EdkShellBinPkg/FullShell/X64/Shell_Full.efi

I will not lie, I don't know exactly what this does, but is a program, you put on the tools folder and YOU WILL PASS A SHELL SCRIPT TO BE RUNNED AS A PARAMETER TO THIS PROGRAM.

So, as you can see on this part of my refind.conf entry, here's the parameter:

options "fs0:\EFI\tools\startup.nsh"

You should CREATE this file that was passed as a parameter too, and there you will put that damn commands that solve yout life. Mine (startup.nsh) as follows:

mm 0010003E 1 ;PCI :8
mm 02000004 1 ;PCI :7

So that's it, here I am writing from my Windows 10 with this damn Nvidia Driver 341.74 that took me 2 entire days rebooting, repairing, reinstalling, updating, until I finally found the complete solution.

So if you get this repair / restart / loop installing Windows 10 on EFI, this is the way to go. I expect in future to find a way with less intermediate programs to boot my macbook.


For those of you that are having trouble on older Macs, try to change startup.nsh values to:

mm 0010003E 1 ;PCI :8
mm 03000004 1 ;PCI :7

This startup.nsh code worked on my MacBook 5,3 to startup Windows with integrated card only

set -v efishellmode 1.1.2 mm 0750 -IO 0 set -v efishellmode 1.1.2 mm 02000004 -PCI 7 set -v efishellmode 1.1.2 mm 0010003E -PCI 8 set -v efishellmode 1.1.2 mm 03000004 -PCI 7

The main difference from code from other posts is the first line that disables 9600 off. Without it, Windows cannot decide which one graphics card to use and goes to black screen. (The credits goes to this great post https://forums.macrumors.com/threads/win7-x64-booting-natively-via-efi-no-bios-emulation.696523/page-42#post-20529412)

The code renews environment variable efishellmode to 1.1.2 to get advantage of advanced mm command syntax.


I had a similar problem on a Mac book pro 2009 (MacBookPro5,5) trying to run windows 10.

I used the details here (https://forums.macrumors.com/threads/win7-x64-booting-natively-via-efi-no-bios-emulation.696523/page-10#post-14101770) to figure out the register settings, I will explain in a bit more detail how that worked:

Step 1. Get an efi shell.
For me, I tried shell from the Tianocore project (official opensource community which grew from Intel Tiano project) and it simply hung on shell startup. In the end I found the shell.efi from the refit project worked for me (http://refit.sourceforge.net/). I used refind (https://www.rodsbooks.com/refind/) - see the section Installing Additional Components https://www.rodsbooks.com/refind/installing.html#addons - basically put shell.efi into EFI\Tools folder.

Step 2. Find your VGA/Graphics adapter.
At the EFI shell, type pci -b to list the PCI devices in the system (seems -b can be added to most commands in the EFI shell to limit the output to a page at a time). I looked through the devices on my system and one of them mentioned VGA. Take note of the Seg Bus Dev and Func identifiers. For me it was

Seg: 00
Bus: 02
Dev: 00

Step 3. Check the register settings.
At the EFI shell type pci -i -b 02 00 00 which equates to pci -i -b <bus> <dev> <func>. Look at the various registers which are displayed, there is a lot of information. I think that register 4, the command register, is probably the most important to look at (it was for me anyway). I noticed that (00) IO space access enabled: was set to zero.

This is the full list from my command register

Command(4): 0002
  (00)I/O space access enabled:       0   (01)Memory space access enabled:    1
  (02)Behave as bus master:           0   (03)Monitor special cycle enabled:  0
  (04)Mem Write & Invalidate enabled: 0   (05)Pallet snooping is enabled:     0
  (06)Assert PERR# when parity error: 0   (07)Do address/data stepping:       0
  (08)SERR# driver enabled:           0   (09)Fast back-to-back transact...:  0

Note that the value of the register is given on the first line, 0002. This means that only bit 1 is turned on (bit 0 is worth 1, bit 1 is worth 2, bit 2 is worth 4, bit 3 is worth 8, bit 4 is worth 16, and so on. Just add up any bits you want to get the final value).

For me, I decided to try enabling I/O space access, and of course to leave Memory space access enabled. That's bits 0 and 1 which I need.

So we need to add 1+2 to get the value of 3. That covers the graphics adapter.

Next we need to find the PCI-PCI bridge which is between bus zero and the graphics adapter. On the MacBookPro5,5 it is indeed the bridge at PCI bus 00, dev 10 (which is decimal 16). You can also confirm this from within windows device manager, select view->devices by connection, then locate your graphics adapter. Note the PCI-PCI Bridge devices between the graphics adapter and the PCI root. Long story short, we also need to set 001000 reg 3E to value of 8. If you have multiple PCI bridges between the graphics adapter and the root, you should set reg 3E in each of them to 8. It is probably unlikely you need to touch more than one bridge though.

Step 4. Test if this works.
To test this, we use the mm command at the EFI shell. You need to figure out the "address" by joining together the seg, bus, dev, func and register addresses.

Seg: 00
Bus: 02
Dev: 00
Reg: 04

The address is made up like ssbbddffrr where ss is seg, bb is bus, dd is dev, ff is func, rr is reg. So for me, I needed the address 0002000004 for the graphics adapter, and 000010003E for the PCI bridge.

Type mm -PCI 0002000004 and press enter. You will see something like

PCI 0x0000000002000004 : 0x02 > _

This means that the current value is 0x02, which is what we expected from the pci -i command. If you don't see the value you expect after the colon, double check your address. We can enter a new value here. (Note, if your value you calculated is larger than 9, you will need to convert from decimal to hexadecimal to use the mm command. Google that if you need help).

So I entered 3 and pressed enter. You will see the mm command will then output the next address. To stop, enter q or .. You can run the mm command again just to check if you actually changed the register value, (again enter q to stop the mm command).

Do the same for the PCI bridge, set the 3E reg to 8.

Now test booting windows as explained in other answers, type something like fs0:\EFI\Microsoft\Boot\bootmgfw.efi into the efi shell.

Step 5. Create the boot script.
The shell.efi program I got from refit automatically looks for startup.nsh script from the EFI\Tools folder on startup (well, presumably in the same folder as shell.efi). So I created this file (use edit command in efi shell, or mount EFI partition from windows or whatever) and I entered the lines

mm 0002000004 ;PCI :3
mm 000010003E ;PCI :8

As noted by others, the syntax for mm is different if you are at the shell or in a script. Why, I have no idea. But near as I can tell, it interprets anything after the semicolon as the access type (PCI) and the colon gives the value. Other people have an extra digit 1 between the address and the access type, this seems to be the access width, 1 is 1 byte, which is the default for mm. This really is not documented anywhere and I figured it out by trial and error.

That's it! I hope this helps somebody else out there :)

Not the answer you're looking for? Browse other questions tagged or ask your own question.