What's the Memory Before 0X08048000 Used for in 32 Bit MAChine

What's the memory before 0x08048000 used for in 32 bit machine?

The answer is really: a bunch of things. There is no magical meaning to the load address of the executable and pretty much anything can be mapped to the lower addresses. Common examples including: C library (such as the C library), the dynamic loader ld.so and the kernel VDSO (kernel mapped dynamic code library that provides some of the interface to the kernel in x86 Linux). But you can pretty much map anything you desire there, using the mmap() system call.

For example on my specific machine the map is as follows (acquired but "cat /proc/self/maps"):

gby@watson:~$ cat /proc/self/maps 
001c0000-00317000 r-xp 00000000 08:01 245836 /lib/libc-2.12.1.so
00317000-00318000 ---p 00157000 08:01 245836 /lib/libc-2.12.1.so
00318000-0031a000 r--p 00157000 08:01 245836 /lib/libc-2.12.1.so
0031a000-0031b000 rw-p 00159000 08:01 245836 /lib/libc-2.12.1.so
0031b000-0031e000 rw-p 00000000 00:00 0
00376000-00377000 r-xp 00000000 00:00 0 [vdso]
00852000-0086e000 r-xp 00000000 08:01 245783 /lib/ld-2.12.1.so
0086e000-0086f000 r--p 0001b000 08:01 245783 /lib/ld-2.12.1.so
0086f000-00870000 rw-p 0001c000 08:01 245783 /lib/ld-2.12.1.so
08048000-08051000 r-xp 00000000 08:01 2244617 /bin/cat
08051000-08052000 r--p 00008000 08:01 2244617 /bin/cat
08052000-08053000 rw-p 00009000 08:01 2244617 /bin/cat
09ab5000-09ad6000 rw-p 00000000 00:00 0 [heap]
b7502000-b7702000 r--p 00000000 08:01 4456455 /usr/lib/locale/locale-archive
b7702000-b7703000 rw-p 00000000 00:00 0
b771b000-b771c000 r--p 002a1000 08:01 4456455 /usr/lib/locale/locale-archive
b771c000-b771e000 rw-p 00000000 00:00 0
bfbd9000-bfbfa000 rw-p 00000000 00:00 0 [stack]

What's the size of virtual memory of the Linux kernel occupies in a 48GB memory, 64-bit machine?

AMD64 uses addresses of "canonical form" (see pages 131-135 here) for implementations that do not implement the full 64 bits. The rationale behind this weird scheme is that it is possible to add more bits in the future as hardware evolves, and the two halves will grow together towards the middle.

Currently, all implementations (i.e. all existing processors) have 48 bit addresses, thus 00000000'00000000--00007FFF'FFFFFFFF, and FFFF8000'00000000--FFFFFFFF'FFFFFFFF are valid address ranges, with 128TB of memory in each half of the usable address space (256TB total).

So that would be 128TB, which is also the maximum per-process address space under Linux under AMD64.

Why does high-memory not exist for 64-bit cpu?

A 32-bit system can only address 4GB of memory. In Linux this is divided into 3GB of user space and 1GB of kernel space. This 1GB is sometimes not enough so the kernel might need to map and unmap areas of memory which incurs a fairly significant performance penalty. The kernel space is the "high" 1GB hence the name "high memory problem".

A 64-bit system can address a huge amount of memory - 16 EB -so this issue does not occur there.

Virtual memory usage

First of all keep in mind that the diagram you posted is pedagogical in nature, rather than factual.

All virtual memory systems divide the logical address range into a user space and system space. That is a totally correct portrayal in the diagram. The placement of things within those areas can vary widely.

You were specifically asking about the low end. It is common for loaders to set up the virtual address space such that the first page (or first several pages) are not mapped into the address space. The logical addresses starting at zero will not be accessible by default. This is done to catch null point references.

Why do Linux program .text sections start at 0x0804800 and stack tops start at 0xbffffff?

Let's start by saying this: most of the time, the various sections do not need to be placed in a specific location, what matters more is the layout. Nowadays, the stack top is actually randomised, see here.

0x08048000 is the default address on which ld starts the first PT_LOAD segment on Linux/x86. On Linux/amd64 the default is 0x400000 and you can change the default by using a custom linker script. You can also change where .text section starts with the -Wl,-Ttext,0xNNNNNNNN flag to gcc. To understand why .text is not mapped at address 0, keep in mind that the NULL pointer is usually mapped to ((void *) 0) for convenience. It is useful, then, that the zero page is mapped inaccessible to trap uses of NULL pointers. The memory before the start of .text is actually used by a lot of things; take cat /proc/self/maps as an example:

$ cat /proc/self/maps 
001c0000-00317000 r-xp 00000000 08:01 245836 /lib/libc-2.12.1.so
00317000-00318000 ---p 00157000 08:01 245836 /lib/libc-2.12.1.so
00318000-0031a000 r--p 00157000 08:01 245836 /lib/libc-2.12.1.so
0031a000-0031b000 rw-p 00159000 08:01 245836 /lib/libc-2.12.1.so
0031b000-0031e000 rw-p 00000000 00:00 0
00376000-00377000 r-xp 00000000 00:00 0 [vdso]
00852000-0086e000 r-xp 00000000 08:01 245783 /lib/ld-2.12.1.so
0086e000-0086f000 r--p 0001b000 08:01 245783 /lib/ld-2.12.1.so
0086f000-00870000 rw-p 0001c000 08:01 245783 /lib/ld-2.12.1.so
08048000-08051000 r-xp 00000000 08:01 2244617 /bin/cat
08051000-08052000 r--p 00008000 08:01 2244617 /bin/cat
08052000-08053000 rw-p 00009000 08:01 2244617 /bin/cat
09ab5000-09ad6000 rw-p 00000000 00:00 0 [heap]
b7502000-b7702000 r--p 00000000 08:01 4456455 /usr/lib/locale/locale-archive
b7702000-b7703000 rw-p 00000000 00:00 0
b771b000-b771c000 r--p 002a1000 08:01 4456455 /usr/lib/locale/locale-archive
b771c000-b771e000 rw-p 00000000 00:00 0
bfbd9000-bfbfa000 rw-p 00000000 00:00 0 [stack]

What we see here is the C library, the dynamic loader ld.so and the kernel VDSO (kernel mapped dynamic code library that provides some interfaces to the kernel). Note that the start of the heap is also randomised.



Related Topics



Leave a reply



Submit