Humans do it with access to the register-level data sheets, which are only available under NDA, and usually with access to a logic analyzer for debugging.
Usually, the problem with developing a driver isn't "writing the code," it's "finding documentation for what the code should do."
Usually, the problem with developing a driver isn't "writing the code," it's "finding documentation for what the code should do."