OS has many functions. One of them is providing access by to all the various
devices and filesystems in the system:
Often distinction drawn between device-dependant IO operations (like controlling a hard disk, or network adapter), and device independant parts of OS, responsible for handling device drivers, providing a naming system for system resources, allowing or denying access to devices and files, and basically providing an interface to the lower-level device drivers.
Main goal of device-independant part: hide differences between various
hardware.
In UNIX, simplify: abstract most devices as block devices and character devices.
Block devices. Disks are obvious example. Random access. Read and write whole blocks at a time. Also bitmap screen display might be considered a block device. In principle a filesystem may be hosted on any kind of block device, not just a disk (e.g. RAM 'disk').
Character device. Misnomer, since read and written in terms of bytes, not characters. (Better named 'stream device' because read or written as a continuous stream of bits.) Serial access device (no random access). For example, audio devices, keyboard, network card, modem.
Some devices don't seem to fit in either catagory (good example is a clock). Also, some devices, like mouse, (or keyboard) generate events which are highly timing-dependant, and are rather forced into the catagory of "character device".
Device driver is the hardware-specific code module which is actually responsible for dealing with the hardware (though the OS may take care of messy stuff like interrupts).