Lably
Skip to content

Loader (computing)

Part of an operating system

  • 6 min read
  • 3 chapters

Related on Lably

Through Computing, Operating system and Computer program

All operating systems that support program loading have loaders, apart from highly specialized computer systems that only have a fixed set of specialized programs. Embedded systems typically do not have loaders, and instead, the code executes directly from ROM or similar. In order to load the operating system itself, as part of booting, a specialized boot loader is used. In many operating systems, the loader resides permanently in memory, though some operating systems that support virtual memory may allow the loader to be located in a region of memory that is pageable.

In the case of operating systems that support virtual memory, the loader may not actually copy the contents of executable files into memory, but rather may simply declare to the virtual memory subsystem that there is a mapping between a region of memory allocated to contain the running program's code and the contents of the associated executable file. (See memory-mapped file.) The virtual memory subsystem is then made aware that pages with that region of memory need to be filled on demand if and when program execution actually hits those areas of unfilled memory. This may mean parts of a program's code are not actually copied into memory until they are actually used, and unused code may never be loaded into memory at all.

Responsibilities

In Unix and Unix-like systems, the loader is the handler for the system call execve(). The Unix loader's tasks include:

  1. validation (permissions, memory requirements etc.);
  2. memory-mapping the executable object from the disk into main memory;
  3. copying the command-line arguments into virtual memory;
  4. initializing registers (e.g., the stack pointer);
  5. jumping to the program entry point (_start).

In Microsoft Windows 7 and above, the loader is the LdrInitializeThunk function contained in ntdll.dll, which does the following:

  1. initialisation of structures in the DLL itself (i.e. critical sections, module lists);
  2. validation of executable to load;
  3. creation of a heap (via the function RtlCreateHeap);
  4. allocation of environment variable block and PATH block;
  5. addition of executable and NTDLL to the module list (a doubly-linked list);
  6. loading of KERNEL32.DLL to obtain several important functions, for instance BaseThreadInitThunk;
  7. loading of executable's imports (i.e. dynamic-link libraries) recursively (check the imports' imports, their imports and so on);
  8. in debug mode, raising of system breakpoint;
  9. initialisation of DLLs;
  10. garbage collection;
  11. calling NtContinue on the context parameter given to the loader function (i.e. jumping to RtlUserThreadStart, that will start the executable)

Sign in to keep reading

2 more chapters are free with a Lably account.

More in Computing and communication