首页服务器linux内核是否有main函数(linux内核函数有哪些)

linux内核是否有main函数(linux内核函数有哪些)

时间2023-03-29 16:32:23发布访客分类服务器浏览986
导读:本篇内容主要讲解“linux内核是否有main函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux内核是否有main函数”吧! linux内核有main函数;...
本篇内容主要讲解“linux内核是否有main函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux内核是否有main函数”吧!

linux内核有main函数;main函数是程序的入口,main是应用程序和操作系统之间约定好的一个接口名,所以linux中每个应用程序的第一个函数必须是main。

linux内核源码之main函数解析

这几天一直在纠结:

main函数是程序的入口,一个程序启动后,经过bootloader的初始化就该经main函数进入C语言的世界,但是linux中每个应用程序的开始都是从main函数开始的。linux下有多个应用程序,岂不是有很多个main。那bootloader会知道跳到哪个main?多个main编译怎么不冲突?

在网上搜索了很久,渐渐的有些明白了:

1、main函数是C语言的入口,这句话没错;但是这句话仅仅是一个约定,而非一个亘古不变的铁律!从程序的更为本质的汇编代码来看,只是大家约定汇编初始化完了后,跳到一个名字叫"main"的标号处;言外之意就是这个标号也是可以改名的,比如linux的C语言入口就是start_kernel();从这个标号地址后就是C语言的天下了。用main这个名字仅仅是因为大家的约定而已,不遵守约定能玩的转也行啊,就像苹果充电线啥的都和别人不一样。

2、在编译时是不存多个main函数的!每个应用程序虽说都有一个main函数(从应用程序来看应用程序的入口是main函数哦);但是应用程序都是独立编译的,不会一起编译,操作系统内核就更不可能和应用程序一起编译了!所以根本不存在多个main冲突的!!可能是统一操作系统与应用程序之间的接口,亦或是侧面影响下main是程序入口的说法,main是应用程序和操作系统之间约定好的一个接口名!所以linux中每个应用程序的第一个函数必须是main。除非你改掉了内核调度的接口地方。

3、linux的应用程序的安装启动也可以类比下我们每天都在用的Windows。Windows应用程序的安装其实也是把一些执行文件拷贝到指定的文件夹里(从绿色软件看),点击就可以运行。linux下也是这样。编译好的bin文件放到指定的文件夹目录下,然后用命令启动执行。

/*
*linux/init/main.c
*
*Copyright(C)1991,1992LinusTorvalds
*
*GK2/5/95-ChangedtosupportmountingrootfsviaNFS
*Addedinitrd&
    change_root:WernerAlmesberger&
    HansLermen,Feb'96
*Moanearlyifgccisold,avoidingboguskernels-PaulGortmaker,May'96
*Simplifiedstartingofinit:MichaelA.Griffithgrif@acm.org>
    
*start_kernel->
    rest_init->
    kernel_init创建用户initpid=1
->
    kthreadd管理内核线程pid=x
->
    pid=0,是idle线程
在rest_init中,会创建kernel_init线程,它负责创建用户init进程,完成工作后,自己
化身为idle线程
*/

#includelinux/types.h>
    
#includelinux/module.h>
    
#includelinux/proc_fs.h>
    
#includelinux/kernel.h>
    
#includelinux/syscalls.h>
    
#includelinux/stackprotector.h>
    
#includelinux/string.h>
    
#includelinux/ctype.h>
    
#includelinux/delay.h>
    
#includelinux/ioport.h>
    
#includelinux/init.h>
    
#includelinux/initrd.h>
    
#includelinux/bootmem.h>
    
#includelinux/acpi.h>
    
#includelinux/tty.h>
    
#includelinux/percpu.h>
    
#includelinux/kmod.h>
    
#includelinux/vmalloc.h>
    
#includelinux/kernel_stat.h>
    
#includelinux/start_kernel.h>
    
#includelinux/security.h>
    
#includelinux/smp.h>
    
#includelinux/profile.h>
    
#includelinux/rcupdate.h>
    
#includelinux/moduleparam.h>
    
#includelinux/kallsyms.h>
    
#includelinux/writeback.h>
    
#includelinux/cpu.h>
    
#includelinux/cpuset.h>
    
#includelinux/cgroup.h>
    
#includelinux/efi.h>
    
#includelinux/tick.h>
    
#includelinux/interrupt.h>
    
#includelinux/taskstats_kern.h>
    
#includelinux/delayacct.h>
    
#includelinux/unistd.h>
    
#includelinux/rmap.h>
    
#includelinux/mempolicy.h>
    
#includelinux/key.h>
    
#includelinux/buffer_head.h>
    
#includelinux/page_cgroup.h>
    
#includelinux/debug_locks.h>
    
#includelinux/debugobjects.h>
    
#includelinux/lockdep.h>
    
#includelinux/kmemleak.h>
    
#includelinux/pid_namespace.h>
    
#includelinux/device.h>
    
#includelinux/kthread.h>
    
#includelinux/sched.h>
    
#includelinux/signal.h>
    
#includelinux/idr.h>
    
#includelinux/kgdb.h>
    
#includelinux/ftrace.h>
    
#includelinux/async.h>
    
#includelinux/kmemcheck.h>
    
#includelinux/sfi.h>
    
#includelinux/shmem_fs.h>
    
#includelinux/slab.h>
    
#includelinux/perf_event.h>
    

#includeasm/io.h>
    
#includeasm/bugs.h>
    
#includeasm/setup.h>
    
#includeasm/sections.h>
    
#includeasm/cacheflush.h>
    

#ifdefCONFIG_X86_LOCAL_APIC
#includeasm/smp.h>
    
#endif

staticintkernel_init(void*);
    

externvoidinit_IRQ(void);
    
externvoidfork_init(unsignedlong);
    
externvoidmca_init(void);
    
externvoidsbus_init(void);
    
externvoidprio_tree_init(void);
    
externvoidradix_tree_init(void);

#ifndefCONFIG_DEBUG_RODATA
staticinlinevoidmark_rodata_ro(void){
}
    
#endif

#ifdefCONFIG_TC
externvoidtc_init(void);
    
#endif

/*
*Debughelper:viathisflagweknowthatwearein'earlybootupcode'
*whereonlythebootprocessorisrunningwithIRQdisabled.Thismeans
*twothings-IRQmustnotbeenabledbeforetheflagisclearedandsome
*operationswhicharenotallowedwithIRQdisabledareallowedwhilethe
*flagisset.
*/
boolearly_boot_irqs_disabled__read_mostly;
    

enumsystem_statessystem_state__read_mostly;
    
EXPORT_SYMBOL(system_state);
    

/*
*Bootcommand-linearguments
*/
#defineMAX_INIT_ARGSCONFIG_INIT_ENV_ARG_LIMIT
#defineMAX_INIT_ENVSCONFIG_INIT_ENV_ARG_LIMIT

externvoidtime_init(void);
    
/*DefaultlatetimeinitisNULL.archscanoverridethislater.*/
void(*__initdatalate_time_init)(void);
    
externvoidsoftirq_init(void);
    

/*Untouchedcommandlinesavedbyarch-specificcode.*/
char__initdataboot_command_line[COMMAND_LINE_SIZE];
    
/*Untouchedsavedcommandline(eg.for/proc)*/
char*saved_command_line;
    
/*Commandlineforparameterparsing*/
staticchar*static_command_line;
    

staticchar*execute_command;
    
staticchar*ramdisk_execute_command;
    

/*
*Ifset,thisisanindicationtothedriversthatresettheunderlying
*devicebeforegoingaheadwiththeinitializationotherwisedrivermight
*relyontheBIOSandskiptheresetoperation.
*
*Thisisusefulifkernelisbootinginanunreliableenvironment.
*Forex.kdumpsituaitonwherepreviouskernelhascrashed,BIOShasbeen
*skippedanddeviceswillbeinunknownstate.
*/
unsignedintreset_devices;
    
EXPORT_SYMBOL(reset_devices);


staticint__initset_reset_devices(char*str)
{
    
reset_devices=1;
    
return1;

}
    

__setup("reset_devices",set_reset_devices);


staticconstchar*argv_init[MAX_INIT_ARGS+2]={
"init",NULL,}
    ;

constchar*envp_init[MAX_INIT_ENVS+2]={
"HOME=/","TERM=linux",NULL,}
    ;
    
staticconstchar*panic_later,*panic_param;
    

externconststructobs_kernel_param__setup_start[],__setup_end[];


staticint__initobsolete_checksetup(char*line)
{
    
conststructobs_kernel_param*p;
    
inthad_early_param=0;
    

p=__setup_start;

do{
    
intn=strlen(p->
    str);
    
if(parameqn(line,p->
str,n)){
    
if(p->
early){
    
/*Alreadydoneinparse_early_param?
*(Needsexactmatchonparampart).
*Keepiterating,aswecanhaveearly
*paramsand__setupsofsamenames8(*/
if(line[n]=='\0'||line[n]=='=')
had_early_param=1;

}
    elseif(!p->
setup_func){
    
printk(KERN_WARNING"Parameter%sisobsolete,"
"ignored\n",p->
    str);
    
return1;

}
    elseif(p->
    setup_func(line+n))
return1;

}
    
p++;

}
    while(p__setup_end);
    

returnhad_early_param;

}
    

/*
*Thisshouldbeapprox2Bo*oMipstostart(noteinitialshift),andwill
*stillworkevenifinitiallytoolarge,itwilljusttakeslightlylonger
*/
unsignedlongloops_per_jiffy=(112);
    
EXPORT_SYMBOL(loops_per_jiffy);

staticint__initdebug_kernel(char*str)
{
    
console_loglevel=10;
    
return0;

}

staticint__initquiet_kernel(char*str)
{
    
console_loglevel=4;
    
return0;

}
    
early_param("debug",debug_kernel);
    
early_param("quiet",quiet_kernel);

staticint__initloglevel(char*str)
{
    
intnewlevel;
    
/*
*Onlyupdateloglevelvaluewhenacorrectsettingwaspassed,
*topreventblindcrashes(whenloglevelbeingsetto0)that
*arequitehardtodebug
*/
if(get_option(&
    str,&
newlevel)){
    
console_loglevel=newlevel;
    
return0;

}
    
return-EINVAL;

}
    
early_param("loglevel",loglevel);

/*ChangeNULtermbackto"=",tomake"param"thewholestring.*/
staticint__initrepair_env_string(char*param,char*val)
{

if(val){
    
/*param=valorparam="val"?*/
if(val==param+strlen(param)+1)
val[-1]='=';

elseif(val==param+strlen(param)+2){
    
val[-2]='=';
    
memmove(val-1,val,strlen(val)+1);
    
val--;

}
    else
BUG();

}
    
return0;

}

/*
*Unknownbootoptionsgethandedtoinit,unlesstheylooklike
*unusedparameters(modprobewillfindthemin/proc/cmdline).
*/
staticint__initunknown_bootoption(char*param,char*val)
{
    
repair_env_string(param,val);
    
/*Handleobsolete-styleparameters*/
if(obsolete_checksetup(param))
return0;
    
/*Unusedmoduleparameter.*/
if(strchr(param,'.')&
    &
    (!val||strchr(param,'.')val))
return0;
    
if(panic_later)
return0;

if(val){
    
/*Environmentoption*/
unsignedinti;
    
for(i=0;
    envp_init[i];
i++){

if(i==MAX_INIT_ENVS){
    
panic_later="Toomanybootenvvarsat`%s'";
    
panic_param=param;

}
    
if(!strncmp(param,envp_init[i],val-param))
break;

}
    
envp_init[i]=param;

}
else{
    
/*Commandlineoption*/
unsignedinti;
    
for(i=0;
    argv_init[i];
i++){

if(i==MAX_INIT_ARGS){
    
panic_later="Toomanybootinitvarsat`%s'";
    
panic_param=param;

}

}
    
argv_init[i]=param;

}
    
return0;

}

staticint__initinit_setup(char*str)
{
    
unsignedinti;
    
execute_command=str;
    
/*
*IncaseLILOisgoingtobootuswithdefaultcommandline,
*itprepends"auto"beforethewholecmdlinewhichmakes
*theshellthinkitshouldexecuteascriptwithsuchname.
*Soweignoreallargumentsentered_before_init=...[MJ]
*/
for(i=1;
    iMAX_INIT_ARGS;
    i++)
argv_init[i]=NULL;
    
return1;

}
    
__setup("init=",init_setup);

staticint__initrdinit_setup(char*str)
{
    
unsignedinti;
    
ramdisk_execute_command=str;
    
/*See"auto"commentininit_setup*/
for(i=1;
    iMAX_INIT_ARGS;
    i++)
argv_init[i]=NULL;
    
return1;

}
    
__setup("rdinit=",rdinit_setup);
    
#ifndefCONFIG_SMP
staticconstunsignedintsetup_max_cpus=NR_CPUS;

#ifdefCONFIG_X86_LOCAL_APIC
staticvoid__initsmp_init(void)
{
    
APIC_init_uniprocessor();

}

#else
#definesmp_init()do{
}
while(0)
#endif
staticinlinevoidsetup_nr_cpu_ids(void){
}

staticinlinevoidsmp_prepare_cpus(unsignedintmaxcpus){
}

#endif
/*
*Weneedtostoretheuntouchedcommandlineforfuturereference.
*Wealsoneedtostorethetouchedcommandlinesincetheparameter
*parsingisperformedinplace,andweshouldallowacomponentto
*storereferenceofname/valueforfuturereference.
*/
staticvoid__initsetup_command_line(char*command_line)
{
    
saved_command_line=alloc_bootmem(strlen(boot_command_line)+1);
    
static_command_line=alloc_bootmem(strlen(command_line)+1);
    
strcpy(saved_command_line,boot_command_line);
    
strcpy(static_command_line,command_line);

}
    
/*
*Weneedtofinalizeinanon-__initfunctionorelseraceconditions
*betweentherootthreadandtheinitthreadmaycausestart_kernelto
*bereapedbyfree_initmembeforetherootthreadhasproceededto
*cpu_idle.
*
*gcc-3.4accidentallyinlinesthisfunction,sousenoinline.
*/
static__initdataDECLARE_COMPLETION(kthreadd_done);

staticnoinlinevoid__init_refokrest_init(void)
{
    
intpid;
    
rcu_scheduler_starting();
    //READ-COPYUPDATE启动
/*
*Weneedtospawninitfirstsothatitobtainspid1,however
*theinittaskwillendupwantingtocreatekthreads,which,if
*wescheduleitbeforewecreatekthreadd,willOOPS.
*创建一个内核线程,它的线程函数是kernel_init,pid=1,内核进程
*/
kernel_thread(kernel_init,NULL,CLONE_FS|CLONE_SIGHAND);
    
//numa策略设置
numa_default_policy();
    
//全局链表kthread_create_list中的kthread内核线程都被运行
//kthreadd线程管理和调度其它内核线程
pid=kernel_thread(kthreadd,NULL,CLONE_FS|CLONE_FILES);
    
rcu_read_lock();
    
//通过pid,ini_pid_ns取得kthreadd地址
kthreadd_task=find_task_by_pid_ns(pid,&
    init_pid_ns);
    
rcu_read_unlock();
    
//通知在kthreadd_done条件的kernel_init线程
complete(&
    kthreadd_done);
    
/*
*Thebootidlethreadmustexecuteschedule()
*atleastoncetogetthingsmoving:
*idle线程初始化
*/
init_idle_bootup_task(current);
    
//抢占禁用
schedule_preempt_disabled();
    
/*Callintocpu_idlewithpreemptdisabled*/
cpu_idle();

}

/*Checkforearlyparams.*/
staticint__initdo_early_param(char*param,char*val)
{
    
conststructobs_kernel_param*p;
    
for(p=__setup_start;
    p__setup_end;
p++){
    
if((p->
    early&
    &
    parameq(param,p->
    str))||
(strcmp(param,"console")==0&
    &
    
strcmp(p->
str,"earlycon")==0)
){
    
if(p->
    setup_func(val)!=0)
printk(KERN_WARNING
"Malformedearlyoption'%s'\n",param);

}

}
    
/*Weaccepteverythingatthisstage.*/
return0;

}

void__initparse_early_options(char*cmdline)
{
    
parse_args("earlyoptions",cmdline,NULL,0,0,0,do_early_param);

}

/*Archcodecallsthisearlyon,orifnot,justbeforeotherparsing.*/
void__initparse_early_param(void)
{
    
static__initdataintdone=0;
    
static__initdatachartmp_cmdline[COMMAND_LINE_SIZE];
    
if(done)
return;
    
/*Allfallthroughtodo_early_param.*/
strlcpy(tmp_cmdline,boot_command_line,COMMAND_LINE_SIZE);
    
parse_early_options(tmp_cmdline);
    
done=1;

}

/*
*Activatethefirstprocessor.
*/
staticvoid__initboot_cpu_init(void)
{
    
intcpu=smp_processor_id();
    
/*Markthebootcpu"present","online"etcforSMPandUPcase*/
set_cpu_online(cpu,true);
    
set_cpu_active(cpu,true);
    
set_cpu_present(cpu,true);
    
set_cpu_possible(cpu,true);

}

void__init__weaksmp_setup_processor_id(void)
{

}

void__init__weakthread_info_cache_init(void)
{

}

/*
*Setupkernelmemoryallocators
*/
staticvoid__initmm_init(void)
{
    
/*
*page_cgrouprequirescontiguouspages,
*biggerthanMAX_ORDERunlessSPARSEMEM.
*/
page_cgroup_init_flatmem();
    
mem_init();
    
kmem_cache_init();
    
percpu_init_late();
    
pgtable_cache_init();
    
vmalloc_init();

}

asmlinkagevoid__initstart_kernel(void)
{
    
char*command_line;
    
externconststructkernel_param__start___param[],__stop___param[];
    
/*
*Needtorunasearlyaspossible,toinitializethe
*lockdephash:
*/
//初始化2个hash表-LockDependencyValidator(内核依赖的关系表)
lockdep_init();
    
smp_setup_processor_id();
    //空函数
debug_objects_early_init();
    //初始化内核调试相关
/*
*SetupthetheinitialcanaryASAP:
*/
boot_init_stack_canary();
    //栈溢出保护初始化
//控制组初始化-cgroup-资源任务分组管理
cgroup_init_early();
    
local_irq_disable();
    //关中断
early_boot_irqs_disabled=true;
    
/*
*Interruptsarestilldisabled.Donecessarysetups,then
*enablethem
*/
tick_init();
    //时钟初始化
boot_cpu_init();
    //启动cpu初始化
page_address_init();
    //页面初始化
printk(KERN_NOTICE"%s",linux_banner);
    
setup_arch(&
    command_line);
    //架构相关初始化
mm_init_owner(&
    init_mm,&
    init_task);
    //内存管理初始化
mm_init_cpumask(&
    init_mm);
    //内存管理初始化
setup_command_line(command_line);
    //处理命令行(保存2份)
setup_nr_cpu_ids();
    //cpuid相关
setup_per_cpu_areas();
    //每cpu变量申请空间(包括gdt)
//smp中用来启动的cpu
smp_prepare_boot_cpu();
    /*arch-specificboot-cpuhooks*/
//建立系统内存页区链表
build_all_zonelists(NULL);
    
//内存页相关初始化
page_alloc_init();
    
printk(KERN_NOTICE"Kernelcommandline:%s\n",boot_command_line);
    
//命令行boot_command_line
parse_early_param();
    
//解析参数
parse_args("Bootingkernel",static_command_line,__start___param,
__stop___param-__start___param,
-1,-1,&
    unknown_bootoption);
    
//
jump_label_init();
    
/*
*Theseuselargebootmemallocationsandmustprecede
*kmem_cache_init()
*内存初始化相关
*/
setup_log_buf(0);
    
pidhash_init();
    
vfs_caches_init_early();
    
sort_main_extable();
    
trap_init();
    
mm_init();
    
/*
*Setuptheschedulerpriorstartinganyinterrupts(suchasthe
*timerinterrupt).Fulltopologysetuphappensatsmp_init()
*time-butmeanwhilewestillhaveafunctioningscheduler.
*调度初始化
*/
sched_init();
    
/*
*Disablepreemption-earlybootupschedulingisextremely
*fragileuntilwecpu_idle()forthefirsttime.
*抢占禁用
*/
preempt_disable();

if(!irqs_disabled()){
    
printk(KERN_WARNING"start_kernel():bug:interruptswere"
"enabled*very*early,fixingit\n");
    
local_irq_disable();

}
    
idr_init_cache();
    //idr
perf_event_init();
    //performanceevent
rcu_init();
    //read-copy-update机制
radix_tree_init();
    //radix树机制
/*initsomelinksbeforeinit_ISA_irqs()*/
early_irq_init();
    //中断请求
init_IRQ();
    //中断请求
prio_tree_init();
    //优先查找树
init_timers();
    //时钟
hrtimers_init();
    //High-resolutionkerneltimers高精度内核时钟
softirq_init();
    //软中断
timekeeping_init();
    //时间相关
time_init();
    //时间
profile_init();
    //分配内核性能统计保存的内存
call_function_init();
    //smp中每cpu的call_single_queue初始化
if(!irqs_disabled())
printk(KERN_CRIT"start_kernel():bug:interruptswere"
"enabledearly\n");
    
early_boot_irqs_disabled=false;
    //中断请求开
local_irq_enable();
    //本地中断开
kmem_cache_init_late();
    //kmem后期初始化
/*
*HACKALERT!Thisisearly.We'reenablingtheconsolebefore
*we'vedonePCIsetupsetc,andconsole_init()mustbeawareof
*this.Butwedowantoutputearly,incasesomethinggoeswrong.
*/
console_init();
    //初始化系统控制台结构
if(panic_later)
panic(panic_later,panic_param);
    
//锁依赖信息
lockdep_info();
    
/*
*Needtorunthiswhenirqsareenabled,becauseitwants
*toself-test[hard/soft]-irqson/offlockinversionbugs
*too:
*/
locking_selftest();
    
#ifdefCONFIG_BLK_DEV_INITRD
if(initrd_start&
    &
    !initrd_below_start_ok&
    &

page_to_pfn(virt_to_page((void*)initrd_start))min_low_pfn){
    
printk(KERN_CRIT"initrdoverwritten(0x%08lx0x%08lx)-"
"disablingit.\n",
page_to_pfn(virt_to_page((void*)initrd_start)),
min_low_pfn);
    
initrd_start=0;

}
    
#endif
page_cgroup_init();
    //controlgroups初始化
debug_objects_mem_init();
    //对象调试
kmemleak_init();
    //检测内核内存泄漏的功能
setup_per_cpu_pageset();
    //申请并初始化每cpu页set
numa_policy_init();
    //numa相关
if(late_time_init)
late_time_init();
    
//初始化每cpusched_clock_data=ktime_now
sched_clock_init();
    
calibrate_delay();
    //计算cpuMIPS百万条指令/s
pidmap_init();
    //pid进程id表初始化
anon_vma_init();
    //虚拟地址
#ifdefCONFIG_X86
if(efi_enabled)//efibois
efi_enter_virtual_mode();
    
#endif
thread_info_cache_init();
    //申请thread_info的内存
cred_init();
    //credential健在分配
//根据物理内存大小,计算可创建进/线程数量
fork_init(totalram_pages);
    
proc_caches_init();
    //进程内存初始化
buffer_init();
    //页高速缓存
key_init();
    //红黑树内存,存keys
security_init();
    //安全相关
dbg_late_init();
    //调试相关
vfs_caches_init(totalram_pages);
    //虚拟文件系统初始化
signals_init();
    //sigqueue申请内存,信号系统
/*rootfspopulatingmightneedpage-writeback*/
page_writeback_init();
    //页回写
#ifdefCONFIG_PROC_FS
proc_root_init();
    //proc文件系统初始化
#endif
cgroup_init();
    //cgroup相关
cpuset_init();
    //cpuset相关
taskstats_init_early();
    //进程计数器
delayacct_init();
    //进程延时审计
check_bugs();
    //系统bug相关测试
//acpi总线
acpi_early_init();
    /*beforeLAPICandSMPinit*/
sfi_init_late();
    //SimpleFirmwareInterface
//功能追踪初始化,一种调试工具
ftrace_init();
    
/*Dotherestnon-__init'ed,we'renowalive*/
rest_init();

}

/*Callallconstructorfunctionslinkedintothekernel.*/
staticvoid__initdo_ctors(void)
{
    
#ifdefCONFIG_CONSTRUCTORS
ctor_fn_t*fn=(ctor_fn_t*)__ctors_start;
    
for(;
    fn(ctor_fn_t*)__ctors_end;
    fn++)
(*fn)();

#endif
}
    
boolinitcall_debug;
    
core_param(initcall_debug,initcall_debug,bool,0644);
    
staticcharmsgbuf[64];

staticint__init_or_moduledo_one_initcall_debug(initcall_tfn)
{
    
ktime_tcalltime,delta,rettime;
    
unsignedlonglongduration;
    
intret;
    
printk(KERN_DEBUG"calling%pF@%i\n",fn,task_pid_nr(current));
    
calltime=ktime_get();
    
ret=fn();
    
rettime=ktime_get();
    
delta=ktime_sub(rettime,calltime);
    
duration=(unsignedlonglong)ktime_to_ns(delta)>
    >
    10;
    
printk(KERN_DEBUG"initcall%pFreturned%dafter%lldusecs\n",fn,
ret,duration);
    
returnret;

}

int__init_or_moduledo_one_initcall(initcall_tfn)
{
    
intcount=preempt_count();
    
intret;
    
if(initcall_debug)
ret=do_one_initcall_debug(fn);
    
else
ret=fn();
    
msgbuf[0]=0;
    
if(ret&
    &
    ret!=-ENODEV&
    &
    initcall_debug)
sprintf(msgbuf,"errorcode%d",ret);

if(preempt_count()!=count){
    
strlcat(msgbuf,"preemptionimbalance",sizeof(msgbuf));
    
preempt_count()=count;

}

if(irqs_disabled()){
    
strlcat(msgbuf,"disabledinterrupts",sizeof(msgbuf));
    
local_irq_enable();

}

if(msgbuf[0]){
    
printk("initcall%pFreturnedwith%s\n",fn,msgbuf);

}
    
returnret;

}
    
externinitcall_t__initcall_start[];
    
externinitcall_t__initcall0_start[];
    
externinitcall_t__initcall1_start[];
    
externinitcall_t__initcall2_start[];
    
externinitcall_t__initcall3_start[];
    
externinitcall_t__initcall4_start[];
    
externinitcall_t__initcall5_start[];
    
externinitcall_t__initcall6_start[];
    
externinitcall_t__initcall7_start[];
    
externinitcall_t__initcall_end[];

staticinitcall_t*initcall_levels[]__initdata={

__initcall0_start,
__initcall1_start,
__initcall2_start,
__initcall3_start,
__initcall4_start,
__initcall5_start,
__initcall6_start,
__initcall7_start,
__initcall_end,
}
    ;

staticchar*initcall_level_names[]__initdata={

"earlyparameters",
"coreparameters",
"postcoreparameters",
"archparameters",
"subsysparameters",
"fsparameters",
"deviceparameters",
"lateparameters",
}
    ;

staticvoid__initdo_initcall_level(intlevel)
{
    
externconststructkernel_param__start___param[],__stop___param[];
    
initcall_t*fn;
    
strcpy(static_command_line,saved_command_line);
    
parse_args(initcall_level_names[level],
static_command_line,__start___param,
__stop___param-__start___param,
level,level,
repair_env_string);
    
for(fn=initcall_levels[level];
    fninitcall_levels[level+1];
    fn++)
do_one_initcall(*fn);

}

staticvoid__initdo_initcalls(void)
{
    
intlevel;
    
for(level=0;
    levelARRAY_SIZE(initcall_levels)-1;
    level++)
do_initcall_level(level);

}

/*
*Ok,themachineisnowinitialized.Noneofthedevices
*havebeentouchedyet,buttheCPUsubsystemisupand
*running,andmemoryandprocessmanagementworks.
*
*Nowwecanfinallystartdoingsomerealwork..
*/
staticvoid__initdo_basic_setup(void)
{
    
cpuset_init_smp();
    //smpcpuset相关
usermodehelper_init();
    //khelper单线程工作队列
shmem_init();
    //sheme机制
driver_init();
    //驱动各子系统
init_irq_proc();
    //proc中创建irq目录
do_ctors();
    //内核中所有构造函数,介于.ctors段中的函数
usermodehelper_enable();
    
//所有编译进内核的驱动模块初始化函数
do_initcalls();

}

staticvoid__initdo_pre_smp_initcalls(void)
{
    
initcall_t*fn;
    
for(fn=__initcall_start;
    fn__initcall0_start;
    fn++)
do_one_initcall(*fn);

}

staticvoidrun_init_process(constchar*init_filename)
{
    
argv_init[0]=init_filename;
    
kernel_execve(init_filename,argv_init,envp_init);

}

/*Thisisanon__initfunction.Forceittobenoinlineotherwisegcc
*makesitinlinetoinit()anditbecomespartofinit.textsection
*这是个非Init函数,防止gcc让它内联到init(),并成为Init.text段的一部分
*/
staticnoinlineintinit_post(void)
{
    
/*needtofinishallasync__initcodebeforefreeingthememory
*在释放init内存前,必须完成所有__init代码执行
*/
async_synchronize_full();
    
free_initmem();
    //释放init.*段中的内存
//修改页表,保证只读数据段为只读属性readonly
mark_rodata_ro();
    
//系统运行状态标志
system_state=SYSTEM_RUNNING;
    
//numa默认策略
numa_default_policy();
    
//当前进程不能被杀掉,只为它是init
current->
    signal->
    flags|=SIGNAL_UNKILLABLE;

//如果ramdisk_execute_command变量指定了init程序,执行它
if(ramdisk_execute_command){
    
run_init_process(ramdisk_execute_command);
    
printk(KERN_WARNING"Failedtoexecute%s\n",
ramdisk_execute_command);

}

/*
*Wetryeachoftheseuntilonesucceeds.
*
*TheBourneshellcanbeusedinsteadofinitifweare
*tryingtorecoverareallybrokenmachine.
*又一个程序,看能不能执行,如果不能,则执行下面4个之一
*/
if(execute_command){
    
run_init_process(execute_command);
    
printk(KERN_WARNING"Failedtoexecute%s.Attempting"
"defaults...\n",execute_command);

}
    
run_init_process("/sbin/init");
    
run_init_process("/etc/init");
    
run_init_process("/bin/init");
    
run_init_process("/bin/sh");
    
//两个变量和4个init都不能成功执行,报错
panic("Noinitfound.Trypassinginit=optiontokernel."
"SeeLinuxDocumentation/init.txtforguidance.");

}

staticint__initkernel_init(void*unused)
{
    
/*
*Waituntilkthreaddisallset-up.等待kthreadd的启动完成
*/
wait_for_completion(&
    kthreadd_done);
    
/*Nowtheschedulerisfullysetupandcandoblockingallocations
*
*/
gfp_allowed_mask=__GFP_BITS_MASK;
    
/*
*initcanallocatepagesonanynode
*/
set_mems_allowed(node_states[N_HIGH_MEMORY]);
    
/*
*initcanrunonanycpu.
*/
set_cpus_allowed_ptr(current,cpu_all_mask);
    
//cad_pid为接收Ctrl-alt-del操作的INT信号的进程ID,设置成了init的pid
//说明init可接受这3个键
cad_pid=task_pid(current);
    
//smp系统准备、激活所有cpu
smp_prepare_cpus(setup_max_cpus);
    
do_pre_smp_initcalls();
    
lockup_detector_init();
    
smp_init();
    
sched_init_smp();
    
//初始化设备驱动、内核模块
do_basic_setup();
    
/*Openthe/dev/consoleontherootfs,thisshouldneverfail
*打开/dev/console设备
*/
if(sys_open((constchar__user*)"/dev/console",O_RDWR,0)0)
printk(KERN_WARNING"Warning:unabletoopenaninitialconsole.\n");
    
/*
*复制两次标准输入0,一个是标准输入1,一个是标准错误2
*/
(void)sys_dup(0);
    
(void)sys_dup(0);
    
/*
*checkifthereisanearlyuserspaceinit.Ifyes,letitdoall
*thework
*是否有早期用户空间init进程,有的话,让其执行
*/
if(!ramdisk_execute_command)
ramdisk_execute_command="/init";

if(sys_access((constchar__user*)ramdisk_execute_command,0)!=0){
    
ramdisk_execute_command=NULL;
    
prepare_namespace();

}
    
/*
*Ok,wehavecompletedtheinitialbootup,and
*we'reessentiallyupandrunning.Getridofthe
*initmemsegmentsandstarttheuser-modestuff..
*/
//启动用户空间的init进程
init_post();
    
return0;

}
    

到此,相信大家对“linux内核是否有main函数”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

linuxmain

若转载请注明出处: linux内核是否有main函数(linux内核函数有哪些)
本文地址: https://pptw.com/jishu/699.html
linux gem的作用是什么 Mysql数据库中的存储引擎是什么(mysql数据库中的存储引擎是什么意思)

游客 回复需填写必要信息