Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
Status
The first post of this thread is a WikiPost and can be edited by anyone with the appropiate permissions. Your edits will be public.
Does this mean that changing one variable might affect other variables stored in the same 4kb block.

I am of course concluding that if the max variable size is 2kb, there can be more than one variable stored in a 4kb block ... or is that a wrong conclusion to start with?

"Changing" a variable actually means deleting it and creating a new one. Thus, if you execute nvram MyVariable=Value, then you execute nvram MyVariable=Vague, the instance of MyVariable is first marked as deleted (one bit in the variable's header is changed from 1->0, so the entire block does not need to be erased), then a new entry is created for MyVariable, with a value of Vague.

By continually deleting/adding, they decrease the number of block-erase operations required; they only do block erases when the entire VSS approaches its capacity (when the free space falls below 2048 bytes), or when the user manually requests an NVRAM wipe. In both cases, they block-erase the entire VSS.

Variables are stored contiguously, so yes, there are multiple variables per 4k block. The hypothetical limit would be ~110 variables in a single block, assuming 1-character names and 1-byte values.

If I may include a related issue from another thread:
@Bmju ... do you happen to know what will happen if a process tries to write an NVRAM variable that is larger than the max allowed? The max on Legacy MacPro is apparently 2kb based on findings by @Syncretic . What will happen if something tries to write a 3kb or 4kb sized variable for instance?

If it will simply get discarded without any negative impact, then the UEFI Windows 64kb size might not be a problem at the end of the day. If it is the opposite, I suppose OpenCore could be updated to also filter such out (filter on size) and return a security violation error similar to the Windows Certificates. I just added such a filter to RefindPlus (locally, not yet pushed) but wondering whether it is worth it.
I think that maybe this don't apply to Macs, or at least to all Macs.

One anedoctal example, yesterday I had a crash with my MacPro9,2 MacBookPro9,2 and the aapl,panic-info was over 5KB. Since SIP was enabled I couldn't dump the BootROM, but I saved the nvram -xp to a file. If my back of the napkin math is correct, 5KB base64 encoded = ~3.5KB.


I'm gonna do some investigation for @Bmju to see the needed GUIDs and I'll also check for the maximum entry size I can find.

Edited to correct MacPro9,2 to MacBookPro9,2

I have not really analyzed any BootROMs other than the MP5,1 144.0.0.0.0, but I have done some cursory looking at a few others. It appears that different Macs (e.g. iMac, MacBook Pro) use different variations of Apple's EFI implementation, so it's entirely plausible that a MBP9.2 could allow variables larger than 2048 bytes. The only assertion I can make with any certainty is that the MP5,1 144.0.0.0.0 EFI should always limit variables to 2048 bytes (or, possibly, behave oddly if a larger variable is somehow introduced during PEI/DXE).

The gRT->SetVariable() code should return EFI_INVALID_PARAMETER if an incoming variable would consume more than 2048 bytes (that total includes the 32-byte variable header, the NULL-terminated UTF-16 variable name, and the binary variable value, so the value must by definition be no more than 2012 bytes (given a 1-character variable name)). It appears that post-BootServices (while MacOS is running), the only exposed variable manipulation is via gRT->SetVariable(), so the 2048-byte limit should be enforced for variables coming from MacOS (unless the MacOS NVRAM driver itself tries to discover the NVRAM mapping and directly manipulate the VSS - I haven't looked at the MacOS NVRAM code).

I suppose where I am getting muddled up is that when writing back, changed variables apparently get appended to the end of the store and the existing record just gets invalidated.

So in a case with Var A, B & C of 1kb each in a block plus Var D of 2kb spanning into the next, does a change to Var A mean Vars B, C & D therefore have to go along for the ride to the end of the store ... with Var D taking those from the next block along and so on?

Obviously can't be the case but just trying to understand the likely mechanics.

Concrete (but bogus) example, using round sizes:
Code:
0x0000 VarA (valid)
0x0400 VarB (valid)
0x0800 VarC (valid)
0x0C00 VarD (valid)
0x1000 (Free Space begins)
Now you modify VarA by changing its value to anything other than its existing value.
Code:
0x0000 VarA (deleted) (meaning the "valid" bit was set to 0)
0x0400 VarB (valid)
0x0800 VarC (valid)
0x0C00 VarD (valid)
0x1000 VarA (valid) (new value)
0x1400 (Free Space begins)
No erasures occured; one bit in the original VarA header was changed from 1->0, and the new VarA header/name/value were appended into the Free Space area.

When free space falls below the 2048-byte threshold (round sizes used and example truncated for simplicity):
Code:
0x0000 VarA (deleted)
0x0400 VarB (valid)
0x0800 VarC (deleted)
0x0C00 VarD (valid)
0x1000 VarA (valid)
0x1400 VarE (valid)
0x1800 VarF (deleted)
0x1900 VarC (valid)
0x1D00 VarF (valid)
0x1E00 (Free Space begins)
The valid data gets copied from VSS1 to VSS2:
Code:
0x0000 VarB (valid)
0x0400 VarD (valid)
0x0800 VarA (valid)
0x0C00 VarE (valid)
0x1000 VarC (valid)
0x1400 VarF (valid)
0x1500 (Free Space begins)
Now, VSS1 gets completely block-erased, then VSS2 is copied back to VSS1, after which VSS2 is ignored. (As I understand it, the MP3,1 does not use a second VSS, so it presumably does GC into a RAM buffer, erases the single VSS, then writes the RAM buffer back out - I haven't actually examined the MP3,1 code, so that's speculation.) During the GC operation, each VSS has a "GC in progress" bit that's reset once the writes are complete; if, at boot time, the "GC in progress" bit is found to be set, the affected VSS is invalidated. If, at boot time, VSS1 is found to be marked "GC in progress" but VSS2 is not (presumably because there was a power-off/failure during GC), and VSS2 looks otherwise valid, VSS1 will be erased and VSS2 will be copied to it (a simple disaster-recovery mechanism). (Note that because of this mechanism, a non-empty VSS2 should always contain only valid variables, no deleted ones. Anything other than valid variables + free space in VSS2 indicates a problem.)
 
one bit in the variable's header is changed from 1->0, so the entire block does not need to be erased
If a single bit can be changed without an erase, then what's the purpose of an erase?
Is a single bit the smallest item that can be changed, or is the smallest changeable item a byte, or something larger?
I guess one can look at a flash ram data sheet to find out.
Or maybe this explains it: https://en.wikipedia.org/wiki/Flash_memory#Block_erasure
It says you can change a bit to 0 but you can't change a bit to 1 without erasing the entire block to 1's. In that case, 0 is chosen as the value that represents an invalidated variable. I suppose there's a different byte that is set to 0 to represent a new variable. I guess you could look at UEFIExtract code to be sure.
The block erase process is probably why an nvram extract has lots of padding with 0xFF bytes in the empty areas.
 
If a single bit can be changed without an erase, then what's the purpose of an erase?
Is a single bit the smallest item that can be changed, or is the smallest changeable item a byte, or something larger?
I guess one can look at a flash ram data sheet to find out.
Or maybe this explains it: https://en.wikipedia.org/wiki/Flash_memory#Block_erasure
It says you can change a bit to 0 but you can't change a bit to 1 without erasing the entire block to 1's. In that case, 0 is chosen as the value that represents an invalidated variable. I suppose there's a different byte that is set to 0 to represent a new variable. I guess you could look at UEFIExtract code to be sure.
The block erase process is probably why an nvram extract has lots of padding with 0xFF bytes in the empty areas.

First, some quick background so things will make a little more sense:
Flash memory's "erased" state sets all bits to 1 (e.g. hex 0xFF). You can change one or more bits in any flash byte to 0, but you can't change a 0 to a 1 without an erase operation. While individual bytes can be read or written, erases must occur in 4kB blocks - therefore, if you want to change one bit from 0 to 1, you have to erase the entire 4k block that contains it.

"0 is chosen as the value that represents an invalidated variable" is correct; it was chosen for precisely this purpose (the ability to mark a variable as deleted without having to do a block erase). It's a one-bit field (0x02) within the UINT8 State field in the VARIABLE_HEADER structure. (EDIT: I accidentally wrote VARIABLE_STORE_HEADER, when I meant VARIABLE_HEADER)

"Padding with 0xFF bytes" is the definition of an empty (erased) area. Avoiding unnecessary writes produces less wear-and-tear on the vulnerable flash, so any "unused" bits are left at 1 (which produces a "no write" operation on the chip; the erased byte(s) are left alone). Thus, all "padding" areas will be filled with 0xFF.

EDIT: "I suppose there's a different byte that is set to 0 to represent a new variable." The variables are stored contiguously. The variable header starts with a signature (0x55AA). If that signature is found to be 0xFFFF (the value found in erased/empty space), the code assumes that's the end of the variable list. (If it's neither 0x55AA nor 0xFFFF, the variable list is corrupted.) A new variable is always appended into the free space, which is by definition all 0xFF, so the 0x55AA header plus the "valid" bit being set to 1 indicates a valid variable.
 
Last edited:
  • Like
Reactions: m0bil and Bmju
I suppose there's a different byte that is set to 0 to represent a new variable. I guess you could look at UEFIExtract code to be sure.
Could it not just be a header with "valid" flag?
That is, Variable = Header to Item Before Next Header?
Probably some end tag as would otherwise not know where the last one before the padding ends ... unless padding has a start tag of course.
 
I suppose there's a different byte that is set to 0 to represent a new variable
Could it not just be a header with "valid" flag?
That is, Variable = Header to Item Before Next Header?
Probably some end tag as would otherwise not know where the last one before the padding ends ... unless padding has a start tag of course.
I think @Syncretic's last edit explains this:
EDIT: "I suppose there's a different byte that is set to 0 to represent a new variable." The variables are stored contiguously. The variable header starts with a signature (0x55AA). If that signature is found to be 0xFFFF (the value found in erased/empty space), the code assumes that's the end of the variable list. (If it's neither 0x55AA nor 0xFFFF, the variable list is corrupted.) A new variable is always appended into the free space, which is by definition all 0xFF, so the 0x55AA header plus the "valid" bit being set to 1 indicates a valid variable.
Instead of a zero byte to indicate a valid variable, there's two bytes with some zero bits: 0x55AA plus the "not-deleted" bit which starts as 1. 0x55AA is a magic number that's less likely to be set randomly from corruption.
The end tag is where both bytes have no zero bits: 0xFFFF.
 
I think Syncretic's last edit explains this
Yes, I saw the edit. It went in later.

The gRT->SetVariable() code should return EFI_INVALID_PARAMETER if an incoming variable would consume more than 2048 bytes.
Yes, this size check is in the EDK 2 code but now curious about whether you know how the MaximumVariableSize value is obtained.

Been quite a while ago now, but @joevt may recollect that while we were doing some development stuff, we found that Apple did not appear to have modified their EFI implementation to include QueryVariableInfo which is "the way" to get this info. Actually, it turned out that on a newer Mac unit that identified itself as a UEFI 2.x device, I think it was Joe's 2018 MacMini, QueryVariableInfo was similarly missing.

Just had a light bulb moment right now and concluded the newer device must have more or less had the same old modified EFI 1.x code and that this was just tweaked to present as UEFI 2.x, similar to Joe's ForgeUEFI, possibly because of some hardware upgrade that Apple determined made this OK to do. I'll wager the key change was an NVRAM upgrade and that the identification change from EFI 1.x to UEFI 2.x probably went in around the Trashcan release as it apparently had such an upgrade. Presumably, everything from that point had NVRAM that more or else match UEFI 2.x specs. Need to get RefindPlus logs from a Trashcan at some point.

So if checking the variable size in SetVariable, there must be some other way to get the MaximumVariableSize on such units when QueryVariableInfo appears to be missing on these units (from what we have seen so far).

*EDIT*
2048-byte limit should be enforced for variables coming from MacOS
The concern is not so much with MacOS, since it is possible that knowing which units are supported, and since BootCamp Windows presumably does not write to NVRAM to start with, a MacOS version may never send anything above what those units can manage. Admittedly not the best way to handle things, but not beyond the realms of possibility in a walled garden.

I suppose the main thing is understanding how the variable size limit is fetched when the designated function for getting this appears to be absent.

There is an academic question of why the function would be absent in the first place. My hypothesis is that the result it provides about the other outputs may not be reliable; possibly because of having two VSS stores. You would have thought they would have just hooked their own custom version in that case though.
 
Last edited:
Do these (Types A & B) have other stuff that can help in identifying them in the NVRAM as I am thinking it could be possible to block them, similar to how the Windows Certificates are blocked.

Turns out specifically blocking kernel panic logs is not required at the end of the day since they are only written to the NVRAM because of a default MacOS boot argument of nvram_paniclog=1.

Simply setting a nvram_paniclog=0 argument stops writing panic logs to NVRAM!
 
Hello! Long (long) time lurker. First time poster. I have a MacPro5,1 which had a Windows 7 dual-boot setup. And started taking a long time to boot. I have been following the discovery of ROM corruption and the fixes over the years. Today I finally got around to powering up the machine, getting a clean Mojave install, and dumping with ROMTool.

Indeed, no surprise, the "FreeSpace" entry of interest in UEFITool is completely missing. So it looks like I need a ROM reconstruction. I reached the point in the Rom dumping instructions where it says "DM @tsialex". OFC I sign up to find that I need 2 posts before being _allowed_ to DM! Sigh. @tsialex , can you help me?

Thanks much and sorry for the noise.
 
Hello! Long (long) time lurker. First time poster. I have a MacPro5,1 which had a Windows 7 dual-boot setup. And started taking a long time to boot. I have been following the discovery of ROM corruption and the fixes over the years. Today I finally got around to powering up the machine, getting a clean Mojave install, and dumping with ROMTool.

Indeed, no surprise, the "FreeSpace" entry of interest in UEFITool is completely missing. So it looks like I need a ROM reconstruction. I reached the point in the Rom dumping instructions where it says "DM @tsialex". OFC I sign up to find that I need 2 posts before being _allowed_ to DM! Sigh. @tsialex , can you help me?

Thanks much and sorry for the noise.
Sure, I've sent you a PM.
 
tsialex, after a decade of multibooting cMP 5,1 without knowing about flash issues, I've now become aware thanks to discovering your excellent posts. Dump of my machine shows roughly one third free space, but missing VSS2 and pad in its place. I do not have an older dump. Version is 144. ROM reconstruction needed? Where to go?
 
tsialex, after a decade of multibooting cMP 5,1 without knowing about flash issues, I've now become aware thanks to discovering your excellent posts. Dump of my machine shows roughly one third free space, but missing VSS2 and pad in its place. I do not have an older dump. Version is 144. ROM reconstruction needed? Where to go?
I'll send you a PM, get everything as instructed and I'll check your BootROM image ASAP.
 
  • Like
Reactions: EdMun
@tsialex thanks to all your posts, I enjoyed geeking out a full clean install of High Sierra, Mojave on a cMP 4,1 -> 5,1
Reading through this thread I am ok on VSS' free space for a Dual CPU+8DIMM with 30131.
But I am not seeing the 2nd VSS Store.
The bootrom version is 144...

I don't think I can send you a PM, maybe coz I'm freshly registered.
Will wait for yours when you have a chance, thanks!
 
@tsialex thanks to all your posts, I enjoyed geeking out a full clean install of High Sierra, Mojave on a cMP 4,1 -> 5,1
Reading through this thread I am ok on VSS' free space for a Dual CPU+8DIMM with 30131.
But I am not seeing the 2nd VSS Store.

A lot people that got in contact recently also had the same failure, now it's the most common problem with early-2009 Mac Pros cross-flashed to MP5,1 firmware.

The bootrom version is 144...

I don't think I can send you a PM, maybe coz I'm freshly registered.
Will wait for yours when you have a chance, thanks!

Sure, PM sent, get everything as instructed and I'll check your BootROM image ASAP.
 
  • Like
Reactions: EdMun
While this is a MacPro5,1 thread, MacPro6,1 had a new EFI firmware update with today's Monterey 12.5 DP4, the new EFI was updated from 430.120.6.0 to 430.140.2.0.0:

Screen Shot 2022-06-25 at 01.08.33.png
Screen Shot 2022-06-25 at 01.52.40.png
 
Hi,

After reading up on this forum when I first went on this cMP journey, I dumped my rom according to the guide, appropriate rom chip model, checked the right place, etc…

This flash dump is for a mid 2012 dual cpu model (it came like this from factory) mac pro with all 8 dim slots filled. This dump was right after I upgraded the firmware to 144.00.000, and HAD NOT installed open core or any other sort of software. This was a purely vanilla Mojave install with apples software.

After checking the “usual” amounts of free space in the garbage collection, I got a little worried. The original lifetime owner (who I know) did a lot of professional creative work and never used anything but official apple and developer software. Is my NVRAM healthy? I know in the thread it says if it reports more than usual it may be corrupted, but Im not seeing any symptoms here.

Thanks so much, would love some informed opinions on my computers health. Should I get a reconstructed rom made? Thanks.

-Will
 
Last edited:
Hi,

After reading up on this forum when I first went on this cMP journey, I dumped my rom according to the guide, appropriate rom chip model, checked the right place, etc…

This flash dump is for a mid 2012 dual cpu model (it came like this from factory) mac pro with all 8 dim slots filled. This dump was right after I upgraded the firmware to 144.00.000, and HAD NOT installed open core or any other sort of software. This was a purely vanilla Mojave install with apples software.

After checking the “usual” amounts of free space in the garbage collection, I got a little worried. The original lifetime owner (who I know) did a lot of professional creative work and never used anything but official apple and developer software. Is my NVRAM healthy? I know in the thread it says if it reports more than usual it may be corrupted, but Im not seeing any symptoms here.

Thanks so much, would love some informed opinions on my computers health. Should I get a reconstructed rom made? Thanks.

-Will
Nope, your NVRAM volume at least already have a corrupted header for the secondary VSS, see below:

Missing  2nd VSS store.jpg


You probably already have other issues. I'll send you a PM.
 
Hi,

After reading up on this forum when I first went on this cMP journey, I dumped my rom according to the guide, appropriate rom chip model, checked the right place, etc…

This flash dump is for a mid 2012 dual cpu model (it came like this from factory) mac pro with all 8 dim slots filled. This dump was right after I upgraded the firmware to 144.00.000, and HAD NOT installed open core or any other sort of software. This was a purely vanilla Mojave install with apples software.

After checking the “usual” amounts of free space in the garbage collection, I got a little worried. The original lifetime owner (who I know) did a lot of professional creative work and never used anything but official apple and developer software. Is my NVRAM healthy? I know in the thread it says if it reports more than usual it may be corrupted, but Im not seeing any symptoms here.

Thanks so much, would love some informed opinions on my computers health. Should I get a reconstructed rom made? Thanks.

-Will
I’m about to start the same journey. Mid 2010 Mac Pro, original owner. I’ve been reading all I can about this because I would like to take it from 10.13.6 to 12 and breath some more life into this machine. Tsialex can you pm me as well so i can discuss with you next steps (newbie and can’t send pm direct). Like will, I’m not having any issues yet, but I am sure there is some corruption that has happened and would like to be proactive in remedying this. I’ll send screenshots of the flash dump as soon as I get back home on Monday. It’s a bit nerve wracking starting this process.
 
I’m about to start the same journey. Mid 2010 Mac Pro, original owner. I’ve been reading all I can about this because I would like to take it from 10.13.6 to 12 and breath some more life into this machine. Tsialex can you pm me as well so i can discuss with you next steps (newbie and can’t send pm direct). Like will, I’m not having any issues yet, but I am sure there is some corruption that has happened and would like to be proactive in remedying this. I’ll send screenshots of the flash dump as soon as I get back home on Monday. It’s a bit nerve wracking starting this process.
There are many people here who can and will help you on the journey.

First step is I would pay @tsialex to reconstruct your boot rom so that you have a know good, clean boot rom. This is one of the weakest spots of the cMP over the long haul.

Some other thoughts - always keep a drive with a Mojave install available as a safety net. It is the last supported (with a Metal GPU) version of macOS for our cMPs. This will be your fall back that can boot your MacPro without opencore.

Enjoy.
 
There are many people here who can and will help you on the journey.

First step is I would pay @tsialex to reconstruct your boot rom so that you have a know good, clean boot rom. This is one of the weakest spots of the cMP over the long haul.

Some other thoughts - always keep a drive with a Mojave install available as a safety net. It is the last supported (with a Metal GPU) version of macOS for our cMPs. This will be your fall back that can boot your MacPro without opencore.

Enjoy.
I can preach on this. tsialex just reconstructed mine, cause my computer was in a pinch. He was fast, communicative, and very professional. Unbelievably important to have the peace of mind for this process.
 
Hi all,

I’m still very confused about this whole corruption process.

I’ve been reading a lot of the pages on this thread on the issue, but I can’t seem to understand it so far.

Now that I have a clean perfect bootROM, and reconstructed everything, what should be my next steps?

I want to use dual boot windows with open core, on Mojave. Eventually I will want to upgrade some of the hardware on my machine. Do I need a new firmware each time I get more ram, new gpu, storage? What is safe to do? What corrupts the bootROM other than windows? What can I avoid doing to stop destruction? I know @tsialex freshly reflashes his bootROM every 3 months, if I do that, am I safe to do anything I want? Thanks.

-will
 
Hi all,

I’m still very confused about this whole corruption process.

I’ve been reading a lot of the pages on this thread on the issue, but I can’t seem to understand it so far.

Now that I have a clean perfect bootROM, and reconstructed everything, what should be my next steps?

Use your Mac Pro normally, just avoid booting UEFI Windows installs without OpenCore blocking Windows UEFI SecureBoot.

If you inadvertently boot UEFI Windows without OpenCore, re-flash the never booted BootROM image.

I want to use dual boot windows with open core, on Mojave. Eventually I will want to upgrade some of the hardware on my machine. Do I need a new firmware each time I get more ram, new gpu, storage?

Nope.

What is safe to do? What corrupts the bootROM other than windows?

SoftwareUpdates can also corrupt your NVRAM volume if the garbage collection fails, there are reports of bricks while staging SoftwareUpdates since High Sierra days, but it's much more common now. 12.3 bricked several Mac Pros some months ago.

People usually only pay attention to the BootROM when things already failed. It's not an issue if you follow good practices and re-flash the never booted BootROM image from time to time to avoid any possibility of a failed GC.

What can I avoid doing to stop destruction? I know @tsialex freshly reflashes his bootROM every 3 months, if I do that, am I safe to do anything I want? Thanks.

-will

Again, you have to follow good practices and avoid at all costs Windows SecureBoot signing your BootROM and sequential crashes dumps/kernel panics - don't think twice and throw away any hardware (RAM/disks/GPUs/etc) that are prone to KPs.

KPs can kill your BootROM.
 
  • Like
Reactions: EdMun
@tsialex, thank you for the reconstruction.

Question if I may. I only use my Mac Pro for Pro Tools and nothing else whatsoever.

Should I dump the ROM every 3 months as well ?
 
@tsialex, thank you for the reconstruction.

Question if I may. I only use my Mac Pro for Pro Tools and nothing else whatsoever.

Should I dump the ROM every 3 months as well ?
macOS is frequently interacting with the NVRAM, so, you should check if everything is ok periodically - think that is part of the Mac Pro maintenance/good practices. If you want it to last, you should do it.

Even if you never again reinstall macOS, just boot Mojave (no more software updates) and don't have iCloud configured, limiting considerably the NVRAM usage by macOS, you should flash the never booted BootROM image from time to time since frequent garbage collection wears out the NAND cells considerably more than just flashing the never booted BootROM image.
 
So i followed the advice and flashed my boot rom thanks to @tsialex. Super easy, so a public thanks to him. I built my open core USB loader and am waiting because my NAS just crapped out and I don't want to do this without a backup, but is there any material I can read on how to run bootcamp on an open core machine? I know there is some crazy rewrite the bios stuff that can happen but are there some good instructional videos or sites that I can read to make sure I can have a windows and OS12 on my mac pro 5,1? I have a separate drive for windows so I am not trying to partition a drive to run it, but I also don't want to brick my machine. Can someone point me in the right direction?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.