Sibling comment by lucozade is good. To be more specific, it's because OS-level threads are the only way the kernel gives applications to run any code at all. When an OS-level thread makes a syscall, it ceases to run any application code until that syscall completes- it's just an ordinary function call that also switches to kernel mode.
The OS kernel itself provides both blocking and asynchronous syscalls. So if your OS-level thread is switching between several coroutines, and one of them makes a synchronous read() syscall, the whole OS-level thread blocks and can't run any other coroutines until the read completes. If it instead makes an asynchronous syscall, the kernel returns immediately and the OS-level thread can switch to another coroutine while the first one waits.
The OS kernel itself provides both blocking and asynchronous syscalls. So if your OS-level thread is switching between several coroutines, and one of them makes a synchronous read() syscall, the whole OS-level thread blocks and can't run any other coroutines until the read completes. If it instead makes an asynchronous syscall, the kernel returns immediately and the OS-level thread can switch to another coroutine while the first one waits.