VerbSyringe.kext - a possible different approach to the AppleHDA mess?
Forum » Development / Sound » VerbSyringe.kext - a possible different approach to the AppleHDA mess?
Started by: snickersmdsnickersmd
On: 1225254356|%e %b %Y, %H:%M %Z|agohover
Number of posts: 14
rss icon RSS: New posts
Summary:
coders anyone?
VerbSyringe.kext - a possible different approach to the AppleHDA mess?
snickersmdsnickersmd 1225254356|%e %b %Y, %H:%M %Z|agohover

Some of Toonces' last few posts over in the AppleHDA progress thread got me thinking of a lot of things. As he said, "I'm no programmer," to which I replied, "Neither am I, I'm a reverse engineer." Of course. So if I call myself a reverse engineer, why am I not looking at the source more, I thought.

So I went back to the decompilation I made of the 10.5.5 AppleHDA.kext. First of all, all of the mystery plist settings are actually there and it became evident that we could simply use a disassembly to figure out what MuteGPIO and all that other stuff actually means on Apple's terms.

But before I even did that, I started poking around even deeper into the code. Why does it seem that Apple isn't switching on the EAPD for us on the ALC269? Does the driver not know to do that? Of course not, there's actually a routine for it in the code as well. So why isn't it being called for the nodes that need it?

The answer is in another of Toonces' contentions that the AppleHDA driver is becoming more specialized, as opposed to my theory that they simply should become universal as more and more chips are supported. Sure, in the AppleHDA binary there is reference to a section of code called AppleHDAGenericCodec, but that's because thanks to the Intel HD Audio Spec, the interface to codec itself is generic, but what Apple does with it is totally specific and driver contained.

This is my revised interpretation to what is going on in the code. Please remember that I am not a programmer, have no internal knowledge of what Apple is really doing, and that this is all speculation on my part. Apple has programmed a reusable code block, the GenericCodec, through which it communicates with the Intel HD Audio Codec. On top of that, there are specialized routines, one for each codec chip used, to initiate vendor specific codes for any given codec chip (Realtek, Stac, etc). As far as we are concerned with the Realtek codecs, these would be the 885 and the 262. After this, Apple uses the plist to make implementation or model specific changes to account for how each of their hardware systems actually uses the codec chip and the different modes it can be placed in.

Assuming this is a valid interpretation, why then has the driver been successfully hacked to accommodate other codec chips? I think the answer is luck. Apple didn't intend it, it just so happens that Realtek made it so that most of their chips respond the same way to the same commands. So by hacking AppleHDA.kext and tinkering with the plists, we get the driver to send ALC885 commands to an ALC880 or an 882 or so on, and the 880 just responds because it understands.

So what happens when Realtek puts out a different chip that does not conform in the same way? Or the vendor does something different with it such that you need to issue it other commands before it will work? We know the 269 is different enough that the ALSA driver needed patches to its source code just to work with it. I think that's where we are today with the more advanced AppleHDA.kext. Extra verbs need to be sent, but unlike in Windows, where the UAA driver actually asks the chip, hey what do you need, and then sends it so that it will work, the AppleHDA driver never bothers. It says, hey, if you're not ready after I'm done initializing, well that's your problem. From that point, I think plist manipulation can only bring you so far.

I doubt this is by design; I mean, I don't think Apple is deliberately trying to foil usage of their driver on other hardware. I'm not a fanboy but it just doesn't make sense for a company that produces the only commercial desktop operating system that doesn't require any Activation mess or CD-Key to actively invest in coding countermeasures within the operating system itself. Rather, I think it's just that it would add an extra layer of complexity to their driver code to make UAA style queries, and so they stick with the more stable approach of hard-coding the needed routines. Regardless of Apple's actual intent, we're still no closer to a true driver solution with what they've given us.

Which brings me to my new proposal. The exciting discoveries of verb manipulation show much promise. Of course, we still need to figure out why verb injection doesn't seem to work in the newer AppleHDA kexts while it does in the older kexts and Azalia. In the meantime, the whole mess of needing Reggie and writing scripts and third party sleep routine programs works but it isn't pretty. What we need is a kext.

I propose to code a kext and call it VerbSyringe. What it would do is load up, identify the audio kext loaded, take the correct memory address from the audio kext/IORegistry, and then, based on a documented plist format that we control, injects needed verbs depending on the audio chipset. This way, such a kext could be coded, and it wouldn't matter whether you were using the Azalia driver or the AppleHDA driver — it would be independent, like HDAEnabler is now. Being a kext, we could also stick a routine in there to be included in power management, so that verbs could be sent automatically on wake and reboot, etc. The best part is that if coded properly, we could use a plist to support more than just the ALC269 and basically be future-proof until the ALC300 comes out ;).

A truly useful feature would be to also incorporate HDAEnabler's job, and also make in-memory patches to the HDA Driver so that even the newer ones act like the older Azalia driver with basic, generic routines. If this could be accomplished, then you wouldn't even need to patch AppleHDA kext or its plists, you would only need to install VerbSyringe.

Now, I've never coded a kext before, but I've started reading up and it seems well documented enough, and a kext that simply modifies registers doesn't have to be very complex. What it truly would do is free the end user from having to use scripts or have Reggie installed on their computer or have to enter super user mode for any reason.

Thoughts? Do you think this would be a viable project with practical application? Any pitfalls that I have overlooked? How should we go about doing it? and lastly, volunteers anyone? :)

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
TooncesToonces 1225258878|%e %b %Y, %H:%M %Z|agohover

Sounds great Snickers. Hopefully you'll be able to recruit someone to help code this! I think your assessment of the newer AppleHDA.kext is right on. I agree that Apple most likely isn't poisoning their driver so other things don't work so much as they just don't care if they do or don't. If it works for them, that's all they need. I haven't looked at the stac datasheets but I know that most of the Realtek chips use the same basic config as either the 885 or 262 models. It's hard for me to stop here but I will. I have some other ideas on what might be left to look at but will put that in the other thread where it's meant to go so as not to add too much to this one.

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
AlexaarAlexaar 1231370074|%e %b %Y, %H:%M %Z|agohover

My conclusion, that the ALC269 codec designed for old i82701 ICH6, which AppleAzalia is supported, meanwhile AppleHDA is not. I simply notice, that the others ALC chips (which includes older 262,268) all designed for ICH7 and modern.
So, that means, that is no way to modify AppleHDA plists to make ALC269 works.

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
strongesthylianstrongesthylian 1225255376|%e %b %Y, %H:%M %Z|agohover

Sounds like an interesting proposition. I don't have any clue on how to program kexts or anything, but your explanations seems to make sense. Maybe you should also try posting on InsanelyMac for help on creating the kext.

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
hagglebeefhagglebeef 1225365900|%e %b %Y, %H:%M %Z|agohover

I am working on it….

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
madtuxmadtux 1225413327|%e %b %Y, %H:%M %Z|agohover

I believe taruga did something like this with his HDAudio.kext, it reads the codec and sets (injects) "stuff" in registry, and users with suported cards like 899A(alc885) don't nead patching, but idea of plist is great, and it could be easily adopted cos we can already put multiple codecs with same Layout 12 but diffrent pathmaps, but i believe that thing to use something like reverse of azalia and making her more like alsa would be "easily", coz apple is making more and more specific codec support, and basicly all codecs are made on two codecs 880 and 861 all diffs are thru HdaVerbs

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
snickersmdsnickersmd 1225417412|%e %b %Y, %H:%M %Z|agohover

No, Taruga's kext doesn't do what I want VerbSyringe to do. You are talking about injecting values into the IO Registry and/or configuration. The HDAEnabler.kext that they made makes it possible to inject an EFI string without doing it in the bootloader. The intended goal of VerbSyringe is to be a customizable kext version of the Linux hda_verb utility that sends verbs directly to the codec, without going through the AppleHDA.kext driver or the IO Registry.

If the project is successful, then configuring AppleHDA.kext will be similar to configuring ALSA; that is definitely our end goal.

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
madtuxmadtux 1225419579|%e %b %Y, %H:%M %Z|agohover

Sorry snickersmd, But I am not talking about HDAEneabler.kext, I am talking about HDAudio.kext, that kext is doing what u described, it dumps the codec, sets stuff in registry, enables pathmaps. But it does only with codec supported by AppleHDA bin. That kext and HDAEneabler are parts of never released Taruga 2.0 HDAPatcher

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
snickersmdsnickersmd 1225423814|%e %b %Y, %H:%M %Z|agohover

That still isn't what I want VerbSyringe to do. VerbSyringe is not intended for dumping the codec, it does not set stuff in registry, nor will it enable pathmaps. It sends verb commands directly to memory. This is not being done yet by any tool currently out there, which is why we are currently doing it with Reggie and scripts.

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
madtuxmadtux 1225478889|%e %b %Y, %H:%M %Z|agohover

So basicly idea is: fake our codec id with one in AppleHDA, and put HDAVerbs thru reggie for that card in a form of a plist, xml entry?

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
hagglebeefhagglebeef 1225490396|%e %b %Y, %H:%M %Z|agohover

My thought would be to have a "intercept" layer between HDA and the IOHDAFamily layer. HDA will keep on sending what it think should be right for 885, the intercept layer would send the "right" verbs for ALC269 to the IOHDAFamily layer.

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
hagglebeefhagglebeef 1225495758|%e %b %Y, %H:%M %Z|agohover

Now that I thought more about it, I think we should call it HDAProxy.

Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
snickersmdsnickersmd 1225498911|%e %b %Y, %H:%M %Z|agohover

Functionally correct, but VerbSyringe is just snappy. ;)

Why bother intercepting 885 signals and still talk to IOHDAFamily? The Reggie method isn't that complex, it just puts verbs straight in the codec registers. In my opinion that would be far easier to code than to reverse engineer the Apple HDA API. What you're saying makes sense if you assume that the reason the 269 fails with the 885 driver is because of completely incorrect signals that need to be blocked and the correct ones sent. However, the work with Azalia suggests that we are just short a few commands, doesn't it? In which case, you would have no need to intercept anything, merely add or inject the missing additional commands to complete initialization, hence a syringe rather than a proxy.

@Madtux: Yes, that sounds more accurate. This idea is based on a working understanding of how AppleHDA.kext works and how the current working patches are done.

In the case of people who already have an Apple supported chip (i.e. their mobo already has ALC885) the driver will work perfectly. However, because it is not a real Mac, ALC885 is not detected. Therefore, force detection fix is required. This is accomplished with either EFI strings, ALCInject, or HDAEnabler. No patches to AppleHDA.kext needed.

In the case of people that have other different Realtek codecs that are similar but not exact to ALC885, extra work must be done. Force detection is needed again, since it is not a real Mac. Secondly, AppleHDA.kext needs to be tricked (Codec switch) into thinking ALC885 is present, so we patch the binary and replace 885 with actual codec. Lastly, layouts, pathmaps and pin configs must be customized, requiring plist edit according with data obtained from codec dump etc.

However, in the case of ALC269, and possibly other chips that are not working yet, our current work is showing evidence that AppleHDA.kext is not doing enough to initialize the codec chip, and it seems that we cannot simply add this information using plist edit. Therefore, the fourth fix method is verb addition. This means that once AppleHDA.kext has already loaded plist, and codec is still not ready, we send codec direct commands to "wake up." The evidence for this is that after the driver is properly loaded, and sound is still not working, by using Reggie to send verbs directly to codec, sound works.

Reggie directly accesses memory, but in order to work, people need to install chud, give root privileges, and then use scripts to automate sending extra verbs. This is not easy for newbies, and it is also very time consuming to support. So the idea is to make a kext that automatically loads these extra verbs.

@back to Hagglebeef:
In which case, if we can make a kext that accesses the register for verbs, then there would be no need to actually program something as complicated as an interceptor/proxy. We would only need to add a debug mode to the kext that, instead of loading verbs into the register, watches and logs the verbs that are loaded into the register by AppleHDA.kext. We could turn the mode on and off simply by adding a switch or parameter to the kext's plist.

Furthermore, if you program it in the way you suggest, then you become version dependent on the AppleHDA.kext and IOHDAFamily.kext that you are hacking. Every time Apple would release an update, you might be forced to update your code. The way I am suggesting is as a "piggyback driver" that waits for AppleHDA.kext to do its work (or rather, fail to do its work) and then talks directly with the codec itself without depending on any Apple code. This way, even if the code authors disappear from the scene, it should continue to work for a long time.

last edited on 1225499393|%e %b %Y, %H:%M %Z|agohover by snickersmd + show more
Re: VerbSyringe.kext - a possible different approach to the AppleHDA mess?
hagglebeefhagglebeef 1225926464|%e %b %Y, %H:%M %Z|agohover

My samsung zif drive died on me yesterday just when I was about to start testing my new IOHDABeefFamily.kext :(. I am hoping it is just the zif cable, so I ordered 10 from Hong Kong. Hopefully it will arrive soon. In the mean time, I am going to mod my Acer one.

New post
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License