Download Embedded Linux Primer: A Practical, Real-World

Transcript
Thecodefoundin.../init/main.cisresponsibleforbringingthekerneltolife.Afterstart_kernel()
performssomebasickernelinitialization,callingearlyinitializationfunctionsexplicitlybyname,the
veryfirstkernelthreadisspawned.Thisthreadeventuallybecomesthekernelthreadcalledinit(),
withaprocessid(PID)of1.Asyouwilllearn,init()becomestheparentofallLinuxprocessesin
userspace.Atthispointinthebootsequence,twodistinctthreadsarerunning:thatrepresentedby
start_kernel()andnowinit().Theformergoesontobecometheidleprocess,havingcompletedits
work.Thelatterbecomestheinitprocess.ThiscanbeseeninListing5-9.
Listing5-9.CreationofKernelinitTHRead
staticvoidnoinlinerest_init(void)__releases(kernel_lock){
kernel_thread(init,NULL,CLONE_FS|CLONE_SIGHAND);
numa_default_policy();
unlock_kernel();
preempt_enable_no_resched();
/*
*Thebootidlethreadmustexecuteschedule()
*atleastonetogetthingsmoving:
*/
schedule();
cpu_idle();
}
Thestart_kernel()functioncallsrest_init(),reproducedinListing5-9.Thekernel'sinitprocessis
spawnedbythecalltokernel_thread().initgoesontocompletetherestofthesysteminitialization,
whilethethreadofexecutionstartedbystart_kernel()loopsforeverinthecalltocpu_idle().
Thereasonforthisstructureisinteresting.Youmighthavenoticedthatstart_kernel(),arelatively
large function, was marked with the __init macro. This means that the memory it occupies will be
reclaimedduringthefinalstagesofkernelinitialization.Itisnecessarytoexitthisfunctionandthe
address space that it occupies before reclaiming its memory. The answer to this was for
start_kernel()tocallrest_init(),showninListing5-9,amuchsmallerpieceofmemorythatbecomes
theidleprocess.