Contribute
Register

Easy IOReg Extraction (DSDT, SSDT, Video BIOS, ...)

Status
Not open for further replies.

SJ_UnderWater

Moderator
Joined
Dec 3, 2010
Messages
633
Motherboard
Gigabyte GA-H55M-S2V
CPU
Intel i3-530
Graphics
HIS HD 6570
Mac
  1. iMac
Classic Mac
Mobile Phone
  1. Android
Anyone wanting to extract Data objects using ioreg from Terminal can use the extract below. Uses include extracting your DSDT, SSDT, video BIOS rom, and so on. Replace <selector> with your ioreg selector, <property> with the registry entry's property you wish to extract, and <output> with the desired file name.
Code:
ioreg -arw0 -d1 <selector> | xpath '//key[.="<field>"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/<output>
DSDT:
Code:
ioreg -arw0 -d1 -c AppleACPIPlatformExpert | xpath '//key[.="DSDT"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/DSDT.aml
AMD/ATI BIOS ROM (may have to replace display with GFX0 or similar)
Code:
ioreg -arw0 -d1 -n display | xpath '//key[.="ATY,bin_image"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/vbios.rom
NVidia BIOS ROM (MUST boot with VBIOS=Yes, may have to replace display with GFX0 or similar)
Code:
ioreg -arw0 -d1 -n display | xpath '//key[.="vbios"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/vbios.rom
Make sure you rename the rom <vendor>_<device>.rom if you wish to inject your edited copy with Chimera in /Extra.

--edit
RehabMan has noted that `xpath` may fail when trying to read full plists if you don't have internet access. In this case place " tail -n +3 | " in front of xpath, e.g.
DSDT with internet:
Code:
ioreg -arw0 -d1 -c AppleACPIPlatformExpert | xpath '//key[.="DSDT"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/DSDT.aml
DSDT without internet:
Code:
ioreg -arw0 -d1 -c AppleACPIPlatformExpert | tail -n +3 | xpath '//key[.="DSDT"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/DSDT.aml
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Just FYI...

xpath fails when there is no internet access. It is trying to parse the apple.com in the xml DTD, and chokes all over itself without working internet.

To work around you simply eliminate that line from the ioreg output:
Code:
ioreg -arw0 -d1 -c AppleACPIPlatformExpert > /tmp/ioreg.tmp
head -n 1 ./ioreg.tmp > /tmp/ioreg1.tmp
tail -n +3 ./ioreg.tmp >> /tmp/ioreg1.tmp
cat /tmp/ioreg1.tmp | xpath '//key[.="DSDT"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/DSDT.aml

Also, it works only on Lion/ML, not SL. SL version of ioreg lacks the "-a" flag. You can work around that by building ioreg from newer sources and running it on SL.
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Just FYI...

xpath fails when there is no internet access. It is trying to parse the apple.com in the xml DTD, and chokes all over itself without working internet.

To work around you simply eliminate that line from the ioreg output:
Code:
ioreg -arw0 -d1 -c AppleACPIPlatformExpert > /tmp/ioreg.tmp
head -n 1 ./ioreg.tmp > /tmp/ioreg1.tmp
tail -n +3 ./ioreg.tmp >> /tmp/ioreg1.tmp
cat /tmp/ioreg1.tmp | xpath '//key[.="DSDT"]/following-sibling::*[1]/text()' | base64 -D -o ~/Desktop/DSDT.aml

Also, it works only on Lion/ML, not SL. SL version of ioreg lacks the "-a" flag. You can work around that by building ioreg from newer sources and running it on SL.

You can also use PlistBuddy instead of xpath/base64 ... probably a bit cleaner and easier to understand:
Code:
ioreg -arw0 -d1 -c AppleACPIPlatformExpert > /tmp/ioreg.tmp
/usr/libexec/PlistBuddy -c "Print '0:ACPI Tables:DSDT'" /tmp/ioreg.tmp >~/Desktop/DSDT.aml

PlistBuddy does not require internet access with the raw xml from ioreg.
 

SJ_UnderWater

Moderator
Joined
Dec 3, 2010
Messages
633
Motherboard
Gigabyte GA-H55M-S2V
CPU
Intel i3-530
Graphics
HIS HD 6570
Mac
  1. iMac
Classic Mac
Mobile Phone
  1. Android
the whole point of the command was to have a one-liner, but if you're concerned about internet access and DTD resolution, simply pipe the XML through `tail -n +3` as you have on a separate line above (...-c AppleACPIPlatformExpert | tail -n +3 | xpath...); there is absolutely no need for temporary files. The previous solution required a script with a loop to `xxd` which was incredibly inelegant.
I'm familiar with both `PlistBuddy` and `defaults`, neither of which really works in this case: simple copy-paste IOReg OSData extraction in a simple command which explicitly selects the desired key by name and path.
If SL's `ioreg` doesn't support structured output then a different solution is necessary, possibly stripping the "+-o" lines, appending commas, and interpreting the rest as JSON in `php`, `perl`, or some other.

--edit
I should also point out that "./" is only a requirement to execute files when they arent in $PATH, e.g. ./ioreg -> ioreg. Piping greatly simplifies work in Bash, part of the Unix Way of doing things; if you really have to pass files through in separate commands then `tail -n +3 < infile >outfile` is more explicit.
--edit2
The point of "./" is you may execute a file in a shell if it's in $PATH, _or_ if you specify the absolute path. "./" is merely an acceptable absolute path for files in the current directory. If you were in ~/Downloads, then `/Users/RehabMan/Downloads/filetoexecute` would also work to execute a file whether binary or executable script.
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
the whole point of the command was to have a one-liner, but if you're concerned about internet access and DTD resolution, simply pipe the XML through `tail -n +3` as you have on a separate line above (...-c AppleACPIPlatformExpert | tail -n +3 | xpath...); there is absolutely no need for temporary files. The previous solution required a script with a loop to `xxd` which was incredibly inelegant.

My goal with the head/tail was to eliminate only the offending second line. A temporary file is necessary in that case. I'm well aware of how piping works, but in this case it wasn't possible given the goal.

I'm familiar with both `PlistBuddy` and `defaults`, neither of which really works in this case: simple copy-paste IOReg OSData extraction in a simple command which explicitly selects the desired key by name and path.

PlistBuddy does work -- and, in fact, is easier to understand. It is what we're actually going to use. Nobody is typing this stuff anyway, it is hidden away in a postinstall script in a PKG.

If SL's `ioreg` doesn't support structured output then a different solution is necessary, possibly stripping the "+-o" lines, appending commas, and interpreting the rest as JSON in `php`, `perl`, or some other.

We already have solved the SL "problem" by building our own ioreg from sources... I think I mentioned that.

--edit
I should also point out that "./" is only a requirement to execute files when they arent in $PATH, e.g. ./ioreg -> ioreg. Piping greatly simplifies work in Bash, part of the Unix Way of doing things; if you really have to pass files through in separate commands then `tail -n +3 < infile >outfile` is more explicit.

--edit2
The point of "./" is you may execute a file in a shell if it's in $PATH, _or_ if you specify the absolute path. "./" is merely an acceptable absolute path for files in the current directory. If you were in ~/Downloads, then `/Users/RehabMan/Downloads/filetoexecute` would also work to execute a file whether binary or executable script.


I'm aware that ./ is not necessary and how ./ relates to the cwd (I've been programming computers for 30 years). In our case, the binaries like ioreg are in the PKG and are copied to a location in /tmp. Like I said, no one is going to see this anyway. I only posted some of our findings here, just in case someone else ran into similar problems.

The fact that some of the specifics of our PKG script crept in this post is just an oversight on my part. I will edit the posts...
 

SJ_UnderWater

Moderator
Joined
Dec 3, 2010
Messages
633
Motherboard
Gigabyte GA-H55M-S2V
CPU
Intel i3-530
Graphics
HIS HD 6570
Mac
  1. iMac
Classic Mac
Mobile Phone
  1. Android
i was actually referring to the use of ./ in "head -n 1 ./ioreg.tmp", but at any rate I thought I would provide a sample JSON implementation, which could probably be significantly optimized. The only dependencies are `grep`, `php` and `xxd`, though I'm sure `php` could be replaced with `perl` or `python`. The general procedure is:
Code:
ioreg -rw0 -d1 #SELECTOR# | grep -v '+-o' | php -r 'echo json_decode(preg_replace("/([^{ ])\n\s+([^} ])/","$1,$2",str_replace(array("<\"","\">","= No","= Yes","=","<",">","(",")"),array("[\"","\"]","= false","= true",":","\"","\"","[","]"),trim(stream_get_contents(STDIN)))))->#PATH#;' | xxd -r -p >#FILE#
This method takes the normal JSON-esque `ioreg` output, strips the root/tree lines, then operates on the text in `php`. STDIN is read, trimmed, formatted using several replacements, then commas are added to finish the translation. The resulting text is fed to json_decode which produces an anonymous PHP object, capable of being traversed using the -> notation. Any properties with non-alphanumeric names must be escaped with {"#NAME#"}, like {"ACPI Tables"}. Finally the hexadecimal string is echoed by `php` to xxd which performs the final translation to binary. No temporary files, and no `ioreg` XML dependency. It's not the prettiest, but the number of processes spawned is pretty low considering the manipulation necessary. It probably won't work if more than one registry entry is returned, otherwise the string could be enclosed in [] to make it an array.
AMD/ATI BIOS ROM (may have to replace display with GFX0 or similar)
Code:
ioreg -rw0 -d1 -n display | grep -v '+-o' | php -r 'echo json_decode(preg_replace("/([^{ ])\n\s+([^} ])/","$1,$2",str_replace(array("<\"","\">","= No","= Yes","=","<",">","(",")"),array("[\"","\"]","= false","= true",":","\"","\"","[","]"),trim(stream_get_contents(STDIN)))))->{"ATY,bin_image"};' | xxd -r -p >~/Desktop/vbios.rom
DSDT:
Code:
ioreg -rw0 -d1 -c AppleACPIPlatformExpert | grep -v '+-o' | php -r 'echo json_decode(preg_replace("/([^{ ])\n\s+([^} ])/","$1,$2",str_replace(array("<\"","\">","= No","= Yes","=","<",">","(",")"),array("[\"","\"]","= false","= true",":","\"","\"","[","]"),trim(stream_get_contents(STDIN)))))->{"ACPI Tables"}->DSDT;' | xxd -r -p >~/Desktop/DSDT.aml
 
Joined
Nov 10, 2011
Messages
1,455
Motherboard
GA-H77N-WIFI F4
CPU
i7-3770
Graphics
HD 4000
Mobile Phone
  1. Android
Also, it works only on Lion/ML, not SL. SL version of ioreg lacks the "-a" flag. You can work around that by building ioreg from newer sources and running it on SL.

Quick correction: it doesn't work on Lion too, the -a flag presents only in latest source version, which is used for building the ioreg tool, bundled with ML.

DSDT:
Code:
ioreg -rw0 -d1 -c AppleACPIPlatformExpert | grep -v '+-o' | php -r  'echo json_decode(preg_replace("/([^{ ])\n\s+([^}  ])/","2 лв,3 лв",str_replace(array("<\"","\">","= No","=  Yes","=","<",">","(",")"),array("[\"","\"]","= false","=  true",":","\"","\"","[","]"),trim(stream_get_contents(STDIN)))))->{"ACPI  Tables"}->DSDT;' | xxd -r -p >~/Desktop/DSDT.aml

Nice, now we can throw out the custom ioreg binary from the package! Only have to test it. Thanks!
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Quick correction: it doesn't work on Lion too, the -a flag presents only in latest source version, which is used for building the ioreg tool, bundled with ML.

Thanks for the correction.

Nice, now we can throw out the custom ioreg binary from the package! Only have to test it. Thanks!

Don't you need that ioreg option for EDID generator?
 
Joined
Nov 10, 2011
Messages
1,455
Motherboard
GA-H77N-WIFI F4
CPU
i7-3770
Graphics
HD 4000
Mobile Phone
  1. Android
Don't you need that ioreg option for EDID generator?

Yes, but that's a different package. The universal ioreg binary presents as a runtime-only resource in both the EDID Generator and the DSDT Generator packages, thanks to this new command, I'll just remove it from the DSDT Generator package, but the other copy inside the EDID Generator will stay, it is still needed for the proper work of the EDID Generator script.
 
Status
Not open for further replies.
Top