Archive | Linux kernel Boot RSS feed for this section

The linux boot sequence: start_kernel, and there was light

Continuing with our discussion Kernel Boot, start_kernel() is implicit Process 0 (the PID was initialized to zero, lets not go looking for a process 0 with “ps”), AKA the “root thread”, the grand daddy of all processes to come. And the fall-back guy, as we will see.

Process 0 (PID 0, root thread) spawns off Process 1, known as the kernel_init (kernel thread) process, which will /sbin/init as the thread we just created (created, not scheduled to run.. not just yet).

Then the kernel process to start off other kernel processes is created (kthreadd) aka Process 2.

Process 1 (PID 1) could become the idle thread for the CPU when it executes.

Regardless, we then schedule() (we DID create a process or two hopefully). Nota Bene: when the /sbin/init kernel thread was created, we only have Processes 0 and 1 in the run queue. i.e. Process 1 becometh /sbin/init. Per 2.6.32.2 atleast and for awhile now.

As part of schedule(), processes may have pooped out or popped in, so we will probably find something to run, right ? After all we have just gone through, we have a right to expect to have something to run. Grins.

However, in the unlikely event that we (eventually) no-can-do schedule() in or out, then we cpu_idle for as long as it takes to find a process to run. Oh … this time, under the aegis of Process 0, which, by our own definition, is the last man standing. Also which, we are well aware of, cannot be “ps”-ed.

Please do note, a system-specific idle could have been created by /sbin/init, with PID being what we get, since the init thread and its children created could, in principle, have fork-ed till kingdom come.

We did mention that we needed to, and actually did enable/disable, preemption along the way depending on whether we were ready to schedule() or not. Given that we are within the pale of initialization, and memory locations are of origins and values unknown, caution is indeed the better part of valor. So why not apply that principle to thread info’s also ? Right choice.

Such indeed are the joys of Linux Kernel Programming. Grins ?

We explain these specific Linux Kernel concepts and more in detail in my classes ( Advanced Linux Kernel Programming @UCSC-Extension), and also in other classes that I teach independently. Please take note, and take advantage also, of upcoming training sessions. As always, Feedback, Questions and Comments are appreciated and will be responded to.

Thanks

-Anand

Comments { 0 }

Linux Boot: The Beginning was startup_32, and it was with Linus, and it WAS Linus also

In an earlier post, we referred to startup_32. Well, __start and start_of_setup the target of the int 19h within the boot context, the target of the first start_32 is located at the 1M watermark as we had mentioned.

What is also special about __start is that we see here the first instruction executed within the context of the kernel (in the case of the objdump shown, we have opted out of the “SAFE RESET of the Controller at config time”, because INT19H presumably has done a good thorough job in the boot context), and we are onto creating a nice clean stack and then check out the magic codes of the boot sectors etc –>

By the time we get to the first startup_32, we are in protected mode, memory > 1MB can be accessed (the target of the decompress). The second startup_32 can therefore be located at the 1M watermark (0010 0000h), and with VA relocation at c010 0000h.

What is so special about this watermark ? It is … the first time we have executed instructions beyond the addressing limits set by x86 real-mode (which as we all know is limited in memory access to 0xFFFFF ..

We discuss Linux Kernel startup/boot concepts and more in my classes with kernel code walk throughs and programming assignments ( Advanced Linux Kernel Programming @UCSC-Extension, and also in other classes that I teach independently). Please take note, and take advantage also, of upcoming training sessions. Anand has also written production x86 protected-mode microcode, so is in a unique position to educate on that front. As always, Feedback, Questions and Comments are appreciated and will be responded to.

Comments { 0 }

startup_32 : In how many ways shall I say I Love Thee ?

OK ! I am just talking atleast about about a startup_32 here.

But given that this routine ( or rather two routines with identical name but in different directories) get used at boot time, one after the other…. one just has to say I love thee atleast twice. Perhaps more.

/arch/x86/boot/compressed/head_64.S
/arch/x86/kernel/head_32.S

The startup_32 in the “kernel” area is the starting point for the execution of the “decompressed” kernel. It IS in x86 assembly. And guess the … what ? IT IS … located at the C0100000 watermark (per /proc/kallsyms). Atleast for 2.6.32.2

And it is also where the mapping for the first 8M of memory (Identity and Non-Identity mapped) will be set up before paging is enabled so that both the relocated high-mem to the 3G of PAGE_OFFSET (C0000000) and non-relocated addresses may be addressed by the processor, if only for the duration of the jump (Grep swapper_pg_dir within this file, or better yet grep for “Enable Paging”). This jump is the one that clears the processors prefetch queue just so TLBs may be used for the fetch of the first non-identity mapped instruction following the execution of the jump.

I explain Linux Kernel concepts and more in my classes ( Advanced Linux Kernel Programming @UCSC-Extension, and also in other classes that I teach independently). Please register for email updates and new posts.

-Anand

Comments { 5 }