.. entries always exist in directories.
They are not specific to Linux; all Unixes have them, and POSIX is nearly requiring them. GNU Hurd and VSTa have them too. Perhaps Multics invented them. MS-DOS 3 copied them from Unix, so Windows has them also. IIRC VMS had something similar.
As soon as some program (your shell, the
/bin/ls program, your or some other program using nftw(3), etc, etc....) uses opendir(3), then some readdir(3) will give
. and (another call to
readdir will return)
.. (actually it is the underlying getdents(2)).
I don't know if they -the
.. entries- are provided in every file system or by some common VFS layer in the kernel (and we should not care). Consider that a successful mkdir(2) creates both
.. entries (it is at least the illusion provided by the Linux kernel).
The kernel path resolution layer handles
/) appropriately. Read path_resolution(7). The file path is used to reference a file (which actually is some inode), and the same file can have several paths (and sometimes none).
Any system call (listed in syscalls(2)) dealing with file paths (such as open(2), unlink(2), stat(2) and many others...) goes thru that path resolution layer in the kernel.
. file in a directory is necessary?
It is very useful in some cases. For example you could (by some program or some weird command) create a file named
-r (this is very bad taste). You would use
rm ./-r to remove it (because
rm -r has some very different meaning). And your shell uses the
$PATH variable to find executables. If you have some
ls executable in the current directory (this is also very bad taste) you need to type
./ls to get it running (otherwise
/bin/ls is likely to be found in your
$PATH by execvp(3) or equivalent).
You could even -in principle- have a directory entry for a file named with a single return or tab character, but that is disgusting. How to remove it is left as an exercise to the reader (but it is possible with
Some functions (such as dlopen(3)) are working differently with a file path containing or not a
/. See this.
.. is useful in relative file paths. See also realpath(3).
A related question is why do processes have a working directory (and each process has its own one, that is why
cd needs to be a shell builtin). This is at least for convenience (and historical reasons, e.g. legacy), and also for efficiency. On some systems (think of supercomputers with petabytes of disk) a complete file path could be very long (e.g. have several hundreds of characters) and you don't want to type long file paths, or have all programs dealing with them. See also chdir(2), credentials(7), chroot(2).
On other OSes - notably MS-DOS -, working directories are -slightly- different.
BTW, files are not a must (and they are conventions and abstractions provided by the operating system kernel). Some experimental academic operating systems don't have files because they are implementing some other persistence layer. In the 1960s operating systems provided very different files (than what POSIX is requiring today).
(when you think about them, files are not necessarily the best way to organize information on current computers. Think how difficult it is for you to find a photo amongst many thousands of them, or a letter you wrote many years ago, on your laptop. Let's hope that future OSes will have something better)
Read Operating Systems: Three Easy Pieces (freely downloadable). Implement -as an exercise- your own unix shell (or study the source code of existing ones, since they are free software). See also this.