I thought that I was having the problem that was solved in Bug 193745, but it would seem that I am not. I have a 2008 Mac Pro (NOT a MacBook) that's been happily running FreeBSD for years via MBR partitioned disks. When the Mac sees the MBR partition it kicks in a bunch of bios emulation, which lets freebsd run. I've recently been inspired to try the EFI booting stuff. It has the attraction of enabling the two extra SATA ports on the motherboard (or more accurately, not disabling them as the BIOS emulation appears to...). I updated my svn repo to include the patches from Bug 193745, built and installed everything, and then cd /usr/src/release/ make -DNOPORTS -DNODOC uefi-memstick dd if=uefi-memstick.img of=/dev/da0 bs=1m The memstick booted and the boot sequence displayed in a small window centered in my large monitor, so I believe that I built everything correctly and that I am testing these changes. As before, I end up stuck at Booting... Start @ 0xffffffff802dfd10 The computer appears to be running, the usb key shows activity on and off for a few moments then settles down. If I press&release the power button, the machine shuts itself down successfully. I can't think of any way to get a serial console on the older Mac Pro, nor can I figure out how to ssh into the uefi-memstick image, so I can't tell what it's doing.
*** Bug 202731 has been marked as a duplicate of this bug. ***
Just a thought: Macs have firewire. It may be possible to enable dcons in the kernel and connect another FreeBSD machine to the Mac Pro using firewire and run dconschat on that other FreeBSD machine. Also: if you suspect that the Mac is running FreeBSD fine, you may be able to ssh into the machine and get the dmesg output. If you use DHCP, then it probably has the same IP address as before. I think the only tweak you may need to make is to configure SSHD on the memstick to allow root login (or alternatively, mount the memstick, chroot into it and add a user). I guess what I would want to know at this time is whether VT uses the efifb driver or not. If not, then a solution pivots around finding the answer to the question: why isn't VT not using efifb. If it is already using efifb, then a solution pivots around: why aren't we seeing anything on the monitor? Both questions probably need information about the graphics protocol and graphics mode, which we should be able to get by tweaking the loader.
I'm taking this for now. Hopefully I can drive it to completion...
I'll work on the firewire dcons angle. Now that the mac laptops can boot via UEFI :] I think I can find one w/ firewire and use it on the other end. I know that in the loader, before the kernel boots, the console is "efi" (checked via `show console`). Can I drop an 'ifconfig_em0="inet 192.168.42.123" into /etc/rc.conf on the memstick image and have it use the addr? I guess I'm asking how much of a real system is running underneath the installer?
Revision 287299 (-current) adds a top command to the loader. A pre-compiled loader has been attached for your convenience. The top command can be used to display the current graphics mode (gop get), list all graphics modes (top list) and set a new graphics mode (top set <mode>). Would you mind adding the list of modes to this PR and also check if other modes (if there are multiple) work better?
Created attachment 160507 [details] loader with gop command
I replaced /boot/loader.efi on the memstick image that I built after you committed the other patches with the loader.efi from this bug report. I powered up, held down the option key, selected that device to boot from, and immediately hit the space bar. It loaded /boot/kernel/kernel and then gave me the `OK` prompt. gop does not appear to work, it fails with: gop: Graphics Output Protocol not present (error=14) I've attached a photo.
Created attachment 160508 [details] Photo of attempting to use the `gop` command in /boot/loader.efi Here's the image of booting with your loader.efi and trying to run the gop command.
(In reply to hartzell from comment #8) Ok, great. Now we know why you don't have a console. Your EFI version does not implement the GOP (Graphics Output Protocol). I suspect the kernel will try to use the standard VGA driver, which doesn't work (dcons should help us confirm this). I suspect your EFI implements UGA (Universal Graphics Adapter) instead. I'm not aware of an EFI version with UGA in any of the machines I have access to, so while I can write a loader command for it, I have no way of testing (that I'm aware of).
Created attachment 160511 [details] Loader with 'gop' and 'uga' commands I have a new loader that besides the 'gop' command also has the 'uga' command. Can you try running 'uga' and report back. I tested this in VMware Fusion 8 and VirtualBox 5. The former has UGA, the latter has not.
Also: would you mind checking the version of your firmware. See also: https://support.apple.com/kb/DL95?locale=en_US
The UGA command reports resolution=2560x1600, depth=32, refresh rate=0 It is running firmware: MP31.006C.B05 which appears to be up to date (matches that Apple article). Thanks!
Ok, so your firmware implements the UGA protocol and not the GOP protocol. This is a little bit of a set back, but it's not the end of the road. The kernel needs to know the following bits of information: # resolution in pixels (horizontal and vertical) # pixel format (which bits for which color) # stride (pixels to add to offset in frame buffer to go vertical 1 line) # physical address of the frame buffer We get all that information from GOP. Unfortunately, UGA only gives us the resolution and the color depth (total number of bits in a pixel). There may be a way to determine the other bits of information, but it's a slippery slope. I think some thing like the following may possibly do it (entirely untested): 1. Determine the frame buffer address Not only does the kernel need to know that, we also need to peek into the frame buffer to figure out the pixel format and stride. We may be able to get the address of the frame buffer by iterating the PCI bus and using one of the BARs of the first display adapter. We need it mapped so that we can read the frame buffer, but as a first step we could tell the kernel about it and see if anything shows up on the monitor (i.e. just give the kernel a stride and pixel format and see what happens). 2. Determine the pixel format With the base address of the frame buffer and assuming we can read it, we need to write various color combinations at the very first pixel and read the values from the frame buffer. This tells us 2 things: 1) we can read the frame buffer and we have the right frame buffer address, and 2) we can figure out the pixel format. 3. Determine the stride By writing different colors for the first pixel on the second (scan) line, we can search the frame buffer for the bytes that change every time we write a new pixel. When we find the memory location that changes when we write a pixel, we have found the stride: it's the difference between the address that changes and the base of the frame buffer. Divide by the pixel depth to get it in pixels. With UGA an obsolete protocol, how valuable will it be to add all this code and how reliable will it be in the end (assuming of course it can be done at all)? I wonder if the firmware can be configured to use UGA or GOP and the simplest solution is to change the EFI setting...
There is a related thread here: http://ubuntuforums.org/showthread.php?t=1557326 Running that pipeline with my system running OS X produces: ``` inky:~ hartzell$ sudo ioreg -lw0 |grep manufacturer|cut -b25-80;sudo ioreg -lw0|grep "product-name"|cut -b 25-80;sudo dtrace -qn 'BEGIN{boot_args=((struct boot_args*)(`PE_state).bootArgs);printf("FrameBuff erBase: 0x%08x\nPixelsPerScanLine: %d\nHorizontalResolution: %d\nVerticalResolution: %d", boot_args->Video.v_baseAddr, boot_args->Video.v_rowBytes/4, boot_args->Video.v_width, boot_args->Video.v_height);exit(0)} ' Password: <"Apple Inc."> <"MacPro3,1"> FrameBuff erBase: 0x80060000 PixelsPerScanLine: 4096 HorizontalResolution: 2560 VerticalResolution: 1600 ``` I found this thread through this Ubuntu page on UEFI booting and macs https://help.ubuntu.com/community/UEFIBooting I currently have the NVIDIA GeForce 8800 GT w/ 512MB of RAM installed. I also own (somewhere...) the ATI Radeon HD 2600 XT with 256 MB. If that would make anything easier, please let me know. Is the "stride" the same as "pixels per scanline"? If this ends up working, it'd be great as this is still a pretty useful machine. BUT, it doesn't seem worth sinking a lifetime into. Can we poke around a bit more and see what we can learn? It might just work out.
I almost have firewire/dcons set up, but I'm stuck. I followed the directions here: https://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/kerneldebug-dcons.html I added the following lines to GENERIC and did ran `buildkernel`. options GDB device firewire device dcons device dcons_crom I used the result to build a memstick image. The memsticks loader.conf contains: vfs.mountroot.timeout="10" dcons_crom_load="YES" dcons_gdb=1 boot_multicons="YES" hw.firewire.phydma_enable=1 hw.firewire.dcons_crom.force_console=1 I also have a Macbook Pro running the same memstick image (yay!) but without the loader.conf variables. I boot up, choose live cd, kldload firewire and dcons. When I run fwcontrol, I only see one entry. If I plug and unplug the firewire cable I see a bunch of error-like messages in `dmesg` output. ``` firewire0: 4 nodes, maxhop <= 3 cable IRM irm(3) (me) firewire0: bus manager 3 fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node0: explore_read_quads failure firewire0: New S800 device ID:001f5bfffe08b316 fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node0: explore_read_quads failure fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node0: explore_read_quads failure firewire0: fw_attach_dev:Removing missing device ID:001f5bfffe08b316 fwohci0: fwohci_intr_core: BUS reset fwohci0: fwohci_intr_core: node_id=0x00000000, SelfID Count=3, CYCLEMASTER mode firewire0: 1 nodes, maxhop <= 0 cable IRM irm(0) (me) firewire0: bus manager 0 fwohci0: fwohci_intr_core: BUS reset fwohci0: fwohci_intr_core: node_id=0x00000000, SelfID Count=4, non CYCLEMASTER mode firewire0: 4 nodes, maxhop <= 3 cable IRM irm(3) fwohci0: fwohci_intr_core: BUS reset fwohci0: txd err= f flushed firewire0: fw_explore_node: node2: explore_read_quads failure fwohci0: fwohci_intr_core: node_id=0x00000000, SelfID Count=5, non CYCLEMASTER mode firewire0: 4 nodes, maxhop <= 3 cable IRM irm(3) firewire0: New S800 device ID:001f5bfffe08b316 fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure firewire0: fw_attach_dev:Removing missing device ID:001f5bfffe08b316 fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure firewire0: New S800 device ID:001f5bfffe08b316 fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure firewire0: fw_attach_dev:Removing missing device ID:001f5bfffe08b316 fwohci0: fwohci_intr_core: BUS reset fwohci0: fwohci_intr_core: node_id=0x00000000, SelfID Count=6, non CYCLEMASTER mode firewire0: 4 nodes, maxhop <= 3 cable IRM irm(0) (me) firewire0: root node is not cycle master capable firewire0: bus manager 0 fwohci0: too many cycles lost, no cycle master present? fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure fwohci0: txd err= 3 miss Ack err firewire0: fw_explore_node: node2: explore_read_quads failure ``` If I boot the laptop with the loader.conf variables specified in the dcons page it hangs trying to (or just after) twiddling something bluetooth related (although perhaps I've just lost the console output to the dcons buffer?). Hints, suggestions (and thanks!)?
ps. In case it matters, I'm using both machine's firewire800 connection, the Macbook Pro does not have an older firewire400.
I have dcons/dconschat working from a mac mini. Gives the same error messages as described for the MacBook Pro and usually fwcontrol only reports a single address, but every once in a while it sees the other end. Enabled a getty on the dcons "tty" and I'm typing away happily. If you can help take a swing at the UGA bits (even if they're a bit retro) I'd appreciate it. Thanks!
Created attachment 160540 [details] Loader that mostly supports booting UGA! Ok, this should hopefully almost work. What is expected to be wrong is the stride. What this means is that the console output of the kernel will be skewed to the point of being unreadable, but the important thing I hope works is that you *will* have console output from the kernel! If we have skewed console output, then all that's left is to determine the stride and we have UGA support. If the colors are off, let me know...
I think I may be close to getting it working that I don't want to get distracted with figuring out why dcons doesn't work. It's very possible that dcons hasn't been working for a while and that it takes some effort on my part to fix it all. I'd rather fix the UGA support and leave dcons for someone else :-) If my latest loader isn't an improvement, I may want to look into dcons just so that we can debug stuff. As for the latest loader: It has the 'gop' and 'uga' commands as before, but now it also passes the UGA information to the kernel so that the kernel can boot with UGA. Please use the uga command to see if everything looks fine. The stride is most likely wrong -- don't worry about that for now. If the rest looks ok, try booting and see if there's anything from the kernel on the screen...
Created attachment 160543 [details] photo of loader uga info
Created attachment 160544 [details] photo of console output
Almost worked, just like you said. See the attached photos. Looks like we have 5 copies of the buffer, offset from each other and a bit offset from the left edge. Progress! g.
A commit references this bug: Author: marcel Date: Sun Aug 30 23:58:54 UTC 2015 New revision: 287317 URL: https://svnweb.freebsd.org/changeset/base/287317 Log: Add support for the UGA draw protocol. This includes adding a command called 'uga' to show whether UGA is implemented by the firmware and what the settings are. It also includes filling the efi_fb structure from the UGA information when GOP isn't implemented by the firmware. Since UGA does not provide information about the stride, we set the stride to the horizontal resolution. This is likely not correct and we should determine the stride by trial and error. For now, this should show something on the console rather than nothing. Refactor this file to maximize code reuse. PR: 202730 Changes: head/sys/boot/efi/include/efipciio.h head/sys/boot/efi/include/efiuga.h head/sys/boot/efi/loader/arch/amd64/framebuffer.c
Marcel, your comment says that you still need "pixels per scanline". It seems as if it's included in the output from the script at the ubuntu URL I referenced earlier in the thread. For instance, for my machine, the output included: PixelsPerScanLine: 4096 Are you thinking of just making it a loader variable and let the user fish about?
(In reply to hartzell from comment #24) It could be handy to allow the user to override what the loader figured out. See for example Bug 202309. What if the firmware does have a bug and we need a way to work around it. A loader variable, settable by the user may be just what we need. For your case, I think we can figure out the stride reliably enough that we don't have to puttee burden on the user. See my next updates!
Created attachment 160546 [details] A working UGA loader! This loader should detect the stride and work for you. Let me know!
Created attachment 160547 [details] Code change that implements the logic For your reference.
Well, the uga command hangs, sez nothing, no response from the keyboard. Booting also hangs, right after printing the Start @ 0xffffffff802dfd10
(In reply to hartzell from comment #28) Bummer. Let me add some debugging prints. It'll spam the screen, but should hopefully tell us what's going on. Thanks so far for testing! Unfortunately, I'll have to depend on your testing efforts even more now. Hopefully it doesn't take too many attempts...
Created attachment 160549 [details] UGA loader with debugging prints The following changes have been made relative to the uploaded patch: 1. When flipping bits in the frame buffer, keep the reserved bits 0. 2. Limit the range in which we look for the stride to twice the width. 3. For every pixel print a line with the stride, frame buffer offset, original (raw) value, new value we write and the pixel colors fetches via the BLT operation
It printed up through stride 5119: offset 4ffc, raw=208056a0, new=007fa95f, RGB=000000 Unable to dedermine [SIC] stride and then stopped. power button shut it down cleanly.
Created attachment 160550 [details] Update UGA loader I changed the logic around. Hopefully this will do the trick.
Created attachment 160551 [details] Code change that implements the new logic
This one printed Start @ 0xffffffff803dfd10 ... Found 0 locations and no more output.
Created attachment 160561 [details] UGA loader (update #3) Working in a virtual machine makes one sloppy, because they tend to be a lot more forgiving than real hardware. The updated loader checks the status for all the EFI calls made during the detection and avoids having reserved bits non-zero. If it still doesn't work, then hopefully we have an error that tells us which call is failing. ... but it is a bit frustrating to have it just work in a VM and just *not* on real hardware ;-)
Created attachment 160562 [details] UGA loader (update #4) I simplified the logic so that the comparison isn't sensitive to the color definitions. We read the frame buffer twice and simply look for a difference between the first and second time.
Thanks! I can't test it until this evening. Will let you know how it goes.
It reported No changes in the frame buffer -- error 0 and that was the end of the console output. When I look at the info that was generated by the script at the "ubuntu" link I quoted a couple of days ago, it provided this info: FrameBuff erBase: 0x80060000 PixelsPerScanLine: 4096 HorizontalResolution: 2560 VerticalResolution: 1600 Your working uga command a couple of loader.efi versions ago (from the attached "photo of loader uga info" provided this info: 2560x1600x32, stride 2560 frame buffer: address=80000000, size=10000000 ... We've discovered that the two values for the stride disagree, but now I notice that the frame buffer base disagrees too. Could that be part of the problem?
(In reply to hartzell from comment #38) Ok, so that explains... I did assume the visible part of the frame buffer would start at 0 and if it doesn't then, yes, things don't work.
Created attachment 160663 [details] UGA loader (update #5) For some reason I couldn't test this in my VM. I got an EFI error trying to read from the frame buffer. I did upgrade my VMware Fusion, though I'm unsure about the ordering of events. I any case: this version does exactly the same thing as before, but with the little detail of trying to find the offset in the frame buffer that changes when the upper-left most pixel is changed. This allows us to find the visible part of the frame buffer. Once that's established, we try and find the stride as before. Please test this. If you get an error 3 when reading the frame buffer (before), then I must have messed something up. It's just that I can't find what it could be. Thanks again of all your testing!
Sadly, error 3. Start @ 0xffffffff802dfd10 Error reading frame buffer (before) -- error 3 when I let it boot.
Created attachment 160665 [details] UGA loader (update #6) Ok, found it. This works again in VMware and hopefully it now also works for you.
Bingo. Boots and gives me a console. Nice work!
Here's a ray of sunshine, hopefully it will keep you hammering at this bug. This change to yesterday's -CURRENT ``` root@minnow:/usr/src-CURRENT # svnlite diff Index: sys/boot/efi/loader/arch/amd64/framebuffer.c =================================================================== --- sys/boot/efi/loader/arch/amd64/framebuffer.c (revision 287390) +++ sys/boot/efi/loader/arch/amd64/framebuffer.c (working copy) @@ -168,7 +168,8 @@ if (efifb->fb_addr == 0 || efifb->fb_size == 0) return (1); /* TODO determine the stride. */ - efifb->fb_stride = efifb->fb_width; /* XXX */ + /* efifb->fb_stride = efifb->fb_width; /* XXX */ + efifb->fb_stride = 4096; /* XXX */ return (0); } ``` let me build a loader.efi that gives me a nice console when the machine boots. The loader's from -CURRENT, the rest of the stuff on the memstick is -STABLE, but that doesn't seem to be a problem. Now that I have a console, let me know if there's anything I can generates (pciconf or dmesg or ...) that will make your life easier.
Hmmph. Now I refresh the page and my hardcode hack show up. Oh well. Glad you got it figured out the right way....
A commit references this bug: Author: marcel Date: Thu Sep 3 04:35:18 UTC 2015 New revision: 287422 URL: https://svnweb.freebsd.org/changeset/base/287422 Log: For UGA, the frame buffer address obtained by scanning the PCI BARs does not necessarily correspond to the upper-left most pixel. Scan the frame buffer for which byte changed when changing the pixel at (0,0). Use the same technique to determine the stride. Except for changing the pixel at (0,0), we change the pixel at (0,1). PR: 202730 Tested by: hartzell (at) alerce.com Changes: head/sys/boot/efi/loader/arch/amd64/framebuffer.c
Thanks again for your help. And nicely spotted about the base address of the frame buffer. Without that I would have banged my head against the wall and eventually just have given up!
I hate to say this, but I think that there is a problem, and my simplest explanation is that I tested your final version with my copy of r287317 with the stride hard-coded. After you closed the bug, I updated a copy of the -CURRENT src tree, built it, copied the resulting loader.efi onto the memstick that I've been using and ended up staring at Couldn't find the pixel -- error 0 I tried copying the loader from this bug report (UGA loader (update #6)) and it behaves the same way. When I replace it w/ my r287317+hack, I get things booting again. It's possible that something else is going on, but the most likely explanation I have is that I screwed up. Is there a clean test that I can do to see where we stand. I'm thinking that if I build -CURRENT and then build a uefi-memstick.img and try that, it should have all of the dots connected properly with your work and should either work or not. Does that sound sane?
It's not quite working out of the box.
I think I'm going to approach is differently. Rather than trying to detect the information, I'll use the SMBIOS information to tell me about the machine model. Then, based on the machine model, we'll fill in the bits and pieces and hope things work out. I tried a MacBook (white) and we couldn't read the frame buffer, so I got the same error as you. I made what work, but then moved on to an iMac, which doesn't work and violates all the assumptions I made. If you can send me the output of kenv from you running FreeBSD?
Created attachment 160751 [details] kenv.out from MacPro3,1 running 10.2-STABLE w/ hacked loader.efi Attached is the kenv output from my mid-2008 Mac Pro running 10.2-STABLE via a hacked up loader.efi.
Hmmm. Another data point. Checked out and built -CURRENT world/kernel, then cd release and `make memstick` (uefi-memstick seems to have gone away between STABLE and CURRENT). dd'd the image onto a stick, and WOW, it works. Perhaps I wasn't crazy and there's some cooperation required between the bits in bootx64.efi or ??? There are still things lurking beneath the still surface of the UEFI boot process that I haven't gathered in. Thanks, as always, for the work!
A cleanroom test (i.e. a memory stick image built from -CURRENT current sources) shows that the problem is resolved.
I know this is a day late dollar short kind of thing but I have a very 'newbie' question. I too have a Mac Pro 2008 and get to the efi loader and it gets stuck at Start @ 0xffffffff802dfd10 like many others. I was wondering if there was a way to just copy the patched loader.efi from a flash disk to the install I already I made or whether the patched loader.efi file is now just the standard file available in FreeBSD 11- Current - Thanks
> I was wondering if there was a way to just copy the patched loader.efi from a > flash disk to the install I already I made or whether the patched loader.efi > file is now just the standard file available in FreeBSD 11- Current - Yes, the fix is in both -CURRENT and stable/10. Yes, you should be able to use loader.efi from one of those snapshots.
A commit references this bug: Author: marius Date: Mon Feb 22 00:49:35 UTC 2016 New revision: 295872 URL: https://svnweb.freebsd.org/changeset/base/295872 Log: MFC: r287299 [1] Add a gop command to help diagnose VT efifb problems. The gop command has the following sub-commands: list - list all possible modes (paged) get - return the current mode set <mode> - set the current mode to <mode> MFC: r287317, r287422, r287475, r287489, r287538 [2] Add support for the UGA draw protocol. This includes adding a command called 'uga' to show whether UGA is implemented by the firmware and what the settings are. It also includes filling the efi_fb structure from the UGA information when GOP isn't implemented by the firmware. PR: 207313 [1], 202730 [2] Approved by: re (gjb) Changes: _U stable/10/ stable/10/sys/boot/efi/include/efipciio.h stable/10/sys/boot/efi/include/efiuga.h stable/10/sys/boot/efi/loader/arch/amd64/framebuffer.c