AFAIK all mass storage devices are presented logically as a linearly addressable sequence of bytes, that can be read and written with pread
and pwrite
like any regular file.
Right. That's the crucial difference between direct access devices (disks, on which you can seek, and pread/pwrite are nothing but an atomic seek/read/write combination), and the sequential devices (serial ports are the classic example, seeking on that would make no sense). Files are similar direct access: you can seek anywhere and rear or write (and if you seek to
But: Let's think about why mmap. What's the purpose of using mmap, versus the "traditional" way of interacting with random-access object? It's all about caching: Normal files use the buffer cache of the file system (or OS). From that viewpoint, it makes sense to use mmap: When you first touch a page (with a memory access) on a mmap'ed file, the underlying file system can set up the cache content, read the page from disk (if the operation was a read), or mark the page as having been touched and needing to be written later. Because of caching and its intimate interaction with the VM (virtual memory) subsystem in the kernel, file systems are already organized around memory pages, so mmap is a good fit there.
And now try to do the same with an uncached raw disk. Conceptually, all hell break loose. Say you have a disk, and have mmap'ed the whole thing into the address space of the process. Now someone reads 1 byte from that address space (with a memory read instruction). Do you really want to read a whole 512-byte sector? What do you do with the rest of the page? When do you drop it from cache? How do you deal with the fact that disk sectors are 512 bytes, while memory pages are 4K? Even worse: Someone writes 1 byte (or 1 32-bit or 64-bit word) to a previously unused sector. What now, brown cow? To be correct, you have to either tag the remaining 511 (or 508 or 504) bytes as unknown, or you have to do a read-modify operation. And to make matters worse, disk drivers don't have any mechanism to keep track of dirty sectors that need write-behind. In a nutshell, if you want mmap on a disk device, the device driver will end up implementing a significant fraction of the VM subsystem.
And all that effort for what? Who would ever want to mmap a disk? File systems don't: They run in the kernel, and they use IO calls that are logical relatives of pread and pwrite (in reality, they are significantly more complex, and typically have scatter/gather capability for efficiency). Databases (which also used to use disk partitions for storage) have very elaborate IO backends, with interestingly complex caching implementations, and they know really well how to use pread/pwrite and relatives. For example, the typical software engineering department for a database IO backend for a commercial database will include several dozen software engineering staff members, so they don't need mmap to be implemented for them (they can do it better themselves). Fsck (and a few relatives like mkfs) are written by file system people, and they have libraries for access. So a lot of effort would be needed, for no real-world benefit.
Note that above, the whole problem with implementing mmap on a device arises because of the impedance mismatch between the inherently memory-like interface of mmap, and the absence of caching on disk devices. In Linux, the situation is different: Early on, the Linux kernel made the (back then pretty radical) decision to integrate the cache layer and the connections to the VM subsystem in the block device layer, not in the file system layer. This is quite a different way to architect the lower half of the kernel, and I think at the time, nobody else was doing this in a production system. Matter-of-fact, in Linux if you want to do accesses to a disk device *without* the memory cache, you have to go out of your way to turn caching off by selecting a raw disk. For this reason, mmap'ing a block device is natural and easy in Linux.
I've not heard of there being a cacheable block device layer in FreeBSD; but then, I've not gone out of the way to look for one.
If you are serious about learning the why and how of this, you will end up reading the "black daemon book": It's really called "Design and Implementation of the FreeBSD operating system", the main author is Kirk McKusick (there are other authors), and the current edition is mostly black, and has the head of the daemon on the cover.