In start_kernel() (main.c) there are 3 variables related to memory initialization:
Each device init typically takes memory_start and returns an updated value if it allocates space at memory_start (by simply grabbing it). paging_init() initializes the page tables in the swapper_pg_dir (starting at 0xc0000000) to cover all of the physical memory from memory_start to memory_end. Actually the first 4 MB is done in startup_32 (head.S). memory_start is incremented if any new page_tables are added. The first page is zeroed to trap null pointer references in the kernel.
In sched_init() the ldt and tss descriptors for task are set in the GDT, and loaded into the TR and LDTR (the only time it's done explicitly). A trap gate (0x80) is set up for system_call(). The nested task flag is turned off in preparation for entering user mode. The timer is turned on. The task_struct for task appears in its entirety in <linux/sched.h>.
mem_map is then constructed by mem_init() to reflect the current usage of physical pages. This is the state reflected in the physical memory map of the previous section.
Then moves into user mode with an iret after pushing the current ss, esp, etc. Of course the user segments for task are mapped right over the kernel segments so execution continues exactly where it left off.
The first exec() sets the LDT entries for task to the user values of base = 0x0, limit = TASK_SIZE = 0xc0000000. Thereafter, no process sees the kernel segments while in user mode.