It varies a lot from chip to chip, or - for PC type chips - from socket to socket.
Calin Negru wrote:Do they have a general purpose usage or does the processor have specialized groups of pins where each group talks to certain type of resource
Chips meant for embedded use, IoT-style, may have general I/O-pins that can be configured by software to behave according to this or that signal standard, among maybe 2-4 different ones (but not too different from each other). This rarely if ever means that the CPU switches among different I/O-standards dynamically; at boot time, it configures the chip to the protocol it uses for communicating with other chips, and then is stays that way. The reason for having this configurability is that the CPU manufacturer can offer a single chip model to users of several different I/O-standards. Making two, three, four different chips, one per I/O standard is far more expensive. But note: I am not talking about x86 or x64 chips now - more like 8051 or ARM M0-chips.
When an program is run it’s machincode doesn have the data required to run the sound card or the Mother Board or another piece of hardware because all computers contain hardware that is different, it comes from different vendors.As Dave Kreskowiak pointed out: I/O on 'PC class' (general, x86/x64 or similar), is generally done using some standardized hardware at the physical level, e.g. USB, PCIe, ... (or earlier: FireWire, COM-port, VGA, ...). The external device is responsible for adapting to one such standard at the physical signal level.
The PC uses low-level, usually OS provided driver software for transferring bytes, or frames of multiple bytes, from the CPU out on the interface. This is independent of whatever device is in the other end. The device must be able to receive bytes or frames, but this is given by the standard (e.g. by USB) and is not device dependent. Of course this goes both ways, for both input and output.
The driver for the physical interface offers an API that is independent on the actual electronics, and usually standardized (although there may be a couple alternatives) for that class of physical interface. Say, the low-level USB driver offers a standard API for sending a USB frame to a given USB address.
The byte stream, or contents of the frames, contains commands and data that may differ from device to device. This is where you may need a device specific driver. Say, your scanner software uses a standard format for commands and data called TWAIN. You scanner vendor provides a higher-level driver that offers a TWAIN API, with scanner-related commands, and creates a message struct, which it asks the USB low-level driver to pass to the scanner. If you replace your scanner, the application software may still use TWAIN calls, but that scanner vendor provides a different driver, creating different scanner commands, as required by his scanner model. But both the old and the new driver will send their (different) scanner command structs to the same low-level USB driver API. Note that this higher-level driver doesn't relate to the electronics; it leaves that to the low-level USB driver. (Or in the old days: SCSI or FireWire drivers.)
In practice, there will be more levels of drivers. A scanner specific TWAIN driver doesn't go all the way down to USB low level drivers in one sweep. E.g. a command struct, or even more: returned data, may be far too large for a physical USB frame. So the TWAIN driver creates the struct of arbitrary length, and hands it over to a medium level driver which cuts the struct into suitable small pieces, and labels the pieces appropriately, e.g. with a sequence number, for sending one by one to the USB low level driver. For incoming data, this driver level will receive a lot of small frames from the low level USB driver, collect them in the order given by their sequence numbers, and when all pieces have arrived and been glued together to one large struct, it sends it to the higher TWAIN level (or whatever resides above it).
You may see quite a few driver levels, one above the other. Somewhere I read that the Windows driver model defines 32 levels(!). That doesn't mean that you have 32 driver software packages, only that if your protocol needs to do so-and-so, you should do it after this but before that. The so-and-so's are ordered into 32 groups. One driver package may take care of six consecutive groups, another of the next 8. Often, there will be nothing to do in a lot of the groups.
The lowest driver level(s) is common for all devices. Maybe the next few as well; e.g. splitting a large message into USB frames can be done the same way for all kinds of devices. The higher you climb the stack of driver levels, the more likely it is that from that point and up, you have device specific drivers - until you come close to the application, e.g. the TWAIN API that is common to all (or a lot of) scanners. Anything above that is not device dependent.
For some device classes, there are standards going all the way up from physical drivers to application level. E.g. for mass storage devices, there are USB standards covering magnetic disks, memory sticks, external 'passport' flash disks etc. The device will, in its end of the cable, implement all the relevant driver levels, and do the adaptation to its own technology on top of that. The application program on the PC uses the API to the uppermost driver level, and everything below it, with no concern about the technology at the other end. This of course requires the device to have some sort of CPU to decipher incoming messages and to build a reply message, but today even safety pins come with build in CPUs (maybe not this year's model, but I am sure that 2024 safety pins will have CPUs ).
is it some kind of compile at runtime?A device vendor providing a driver will usually give you a binary, ready to run driver. So he must provide different drivers for CPUs with different instruction sets (e.g. x86, x64, ARM 32 or 64 bits). Usually, a driver is not completely self contained but uses OS services, at least for installation and activation, so there must be different driver versions depending on the OS. They will all be different binary versions, and the installer picks one of them. I.e. no runtime compilation.
Finally: You will rarely if ever see a driver that takes you all the way from the application program down to the physical interface. It will make assumptions that 'someone' provides lower level drivers according to this or that standard. And it will assume that 'If I provide an API according to this or that standard to drivers at higher levels than myself, they will be able to use it'. I have seen quite a few device drivers providing the truly device specific middle/upper layers, but the installer will check if the lower and higher level drivers exist in the system. If they do, they are used. If not, the driver packages has got its own implementation, and they are installed along with the main device driver.
At least for the most part, you are certainly right. It can be argued that, say, when I print an MS-Word document to a Postscript printer, the PS generating function is functionally identical to a top level driver for a PS device. A PDF print routine is a top level driver for a PDF device. Generating the PS or PDF protocol elements is usually done at the application level (it may be done by a library routine, yet at application level.)
Dave Kreskowiak wrote:Drivers are part of the O/S, not the applications.