I'm not sure I understand the source of your confusion, but keep in mind that in Unix the command line arguments (the foo and bar from echo foo bar) and environment strings (the FOO=bar from env - FOO=bar printenv) are simply copied by the kernel in the address space of the process, where they're simply accessed just like any other memory (via pointers, etc.); they're not passed as files that could be read, written or memory mapped by the process, as the standard stdin, stdout, stderr or any extra file descriptors are.
This is not some law of nature, it's just how it works in Unix. An argument could be made that this is archaic, inconsistent and inefficient (a copy of the whole environment is made for each process, even if it ignores all or most of it).
Different arrangements can be made -- in plan9, the environment strings are actually files in /env (which also means that they can be shared between processes).
Also, a LD_PRELOAD hack could be used in Linux to bypass the argv+env limit by passing the whole thing via a file created with memfd_create.
echogets all the information it needs from the arguments passed to it.echogets information from the argv (command line arguments, one of the process's properties).