精华内容
下载资源
问答
  • linux2.6.1内核源码注释

    万次下载 热门讨论 2014-03-10 15:21:33
    包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释。前后历时三年,算是干货。
  • CentOS官网内核源码是通过定制的内核,将大部分的驱动编译成模块的方式,匹配上发行版本的Linux的启动内核,而官网下载的内核需要进行重新的定制编译才可以和发行版本的内核一致,大部分的驱动都编译进内核,导致...

    对比分析:

            CentOS官网内核源码是通过定制的内核,将大部分的驱动编译成模块的方式,匹配上发行版本的Linux的启动内核,而官网下载的内核需要进行重新的定制编译才可以和发行版本的内核一致,大部分的驱动都编译进内核,导致内核过大!!

    场景说明:

        希望编译网卡驱动,所以需要内核源码,(其实这是非常愚蠢的,编译网卡驱动等等需要的是内核的头文件,因为需要调用到内核提供的函数)。在发行版本的光盘中苦苦寻觅。在linux的世界里面最重要的知道路在何方,而不是路在脚下。源代码的官网:http://vault.centos.org/进入官网后,依次是进入 6.5/,进入os/,进入Source/,进入SPackages/,找到 kernel-2.6.32-431.el6.src.rpm,下载就行了。

    如下是详细的地址:

    http://vault.centos.org/6.5/os/Source/SPackages/

    如下wiki提供的一个关于源码下载安装的中文介绍,值得拥有,src.rpm包是一种特殊的安装包:

    http://wiki.centos.org/zh/HowTos/I_need_the_Kernel_Source?highlight=%28kernel%29%7C%28src%29

     根据提供的链接:http://vault.centos.org/7.N.YYMM/os/Source/SPackages/

    打开失败,但是通过进入到http://vault.centos.org就可以下载源码了!

     

    启发:

    如果能够访问到外国的技术网站,就能够获取第一手的资料

    引用老师的一句话:遇到问题,记得google大神!

    如下提供CentOS网站的一些有用信息:

    http://wiki.centos.org/zh/HowTos#head-f63aaa6bb4084c1bbdfc34937435342ae2d90566



         本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1547693,如需转载请自行联系原作者



    展开全文
  • 提示:本文基于开源鸿蒙内核分析,官方源码【kernel_liteos_a】,官方文档【docs】...鸿蒙内核源码分析(Task/线程管理篇) 鸿蒙内核源码分析(进程管理篇) 鸿蒙内核源码分析(调度队列篇) 以便对本文任务调度机制的理解

    鸿蒙内核源码注释中文版 【 Gitee仓 | CSDN仓 | Github仓 | Coding仓 】精读内核源码,中文注解分析.深挖地基工程,构建底层网图.

    鸿蒙源码分析系列篇 【 CSDN | OSCHINA | HarmonyOS 】问答式导读, 生活式比喻, 图形化展示, 层层剥开内核神秘外衣.


    建议先阅读

    阅读之前建议先读本系列其他文章,以便对本文任务调度机制的理解。

    为什么学一个东西要学那么多的概念?

    鸿蒙的内核中 Task 和 线程 在广义上可以理解为是一个东西,但狭义上肯定会有区别,区别在于管理体系的不同,Task是调度层面的概念,线程是进程层面概念。比如 main() 函数中首个函数 OsSetMainTask(); 就是设置启动任务,但此时啥都还没开始呢,Kprocess 进程都没创建,怎么会有大家一般意义上所理解的线程呢。狭义上的后续有 鸿蒙内核源码分析(启动过程篇) 来说明。不知道大家有没有这种体会,学一个东西的过程中要接触很多新概念,尤其像 Java/android 的生态,概念贼多,很多同学都被绕在概念中出不来,痛苦不堪。那问题是为什么需要这么多的概念呢?

    举个例子就明白了:

    假如您去深圳参加一个面试老板问你哪里人?你会说是 江西人,湖南人... 而不会说是张家村二组的张全蛋,这样还谁敢要你。但如果你参加同乡会别人问你同样问题,你不会说是来自东北那旮沓的,却反而要说张家村二组的张全蛋。明白了吗?张全蛋还是那个张全蛋,但因为场景变了,您的说法就得必须跟着变,否则没法愉快的聊天。程序设计就是源于生活,归于生活,大家对程序的理解就是要用生活中的场景去打比方,更好的理解概念。

    那在内核的调度层面,咱们只说task, task是内核调度的单元,调度就是围着它转。

    进程和线程的状态迁移图

    先看看task从哪些渠道产生:

    渠道很多,可能是shell 的一个命令,也可能由内核创建,更多的是大家编写应用程序new出来的一个线程。

    调度的内容task已经有了,那他们是如何被有序调度的呢?答案:是32个进程和线程就绪队列,各32个哈,为什么是32个,鸿蒙系统源码分析(总目录) 文章里有详细说明,自行去翻。这张进程状态迁移示意图一定要看明白.

    注意:进程和线程的队列内的内容只针对就绪状态,其他状态内核并没有用队列去描述它,(线程的阻塞状态用的是pendlist链表),因为就绪就意味着工作都准备好了就等着被调度到CPU来执行了。所以理解就绪队列很关键,有三种情况会加入就绪队列。

    • Init→Ready:

      进程创建或fork时,拿到该进程控制块后进入Init状态,处于进程初始化阶段,当进程初始化完成将进程插入调度队列,此时进程进入就绪状态。

    • Pend→Ready / Pend→Running:

      阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态,若此时发生进程切换,则进程状态由就绪态转为运行态。

    • Running→Ready:

      进程由运行态转为就绪态的情况有以下两种:

    • 有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。

    • 若进程的调度策略为SCHED_RR,且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。

    谁来触发调度工作?

    就绪队列让task各就各位,在其生命周期内不停的进行状态流转,调度是让task交给CPU处理,那又是什么让调度去工作的呢?它是如何被触发的?

    笔者能想到的触发方式是以下四个:

    • Tick(时钟管理),类似于JAVA的定时任务,时间到了就触发。系统定时器是内核时间机制中最重要的一部分,它提供了一种周期性触发中断机制,即系统定时器以HZ(时钟节拍率)为频率自行触发时钟中断。当时钟中断发生时,内核就通过时钟中断处理程序OsTickHandler对其进行处理。鸿蒙内核默认是10ms触发一次,执行以下中断函数:
    /*
     * Description : Tick interruption handler
     */
    LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
    {
        UINT32 intSave;
    
        TICK_LOCK(intSave);
        g_tickCount[ArchCurrCpuid()]++;
        TICK_UNLOCK(intSave);
    
    #ifdef LOSCFG_KERNEL_VDSO
        OsUpdateVdsoTimeval();
    #endif
    
    #ifdef LOSCFG_KERNEL_TICKLESS
        OsTickIrqFlagSet(OsTicklessFlagGet());
    #endif
    
    #if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES)
        HalClockIrqClear(); /* diff from every platform */
    #endif
    
        OsTimesliceCheck();//时间片检查
    
        OsTaskScan(); /* task timeout scan *///任务扫描,发起调度
    
    #if (LOSCFG_BASE_CORE_SWTMR == YES)
        OsSwtmrScan();//软时钟扫描检查
    #endif
    }
    

    里面对任务进行了扫描,时间片到了或就绪队列有高或同级task, 会执行调度。

    • 第二个是各种软硬中断,如何USB插拔,键盘,鼠标这些外设引起的中断,需要去执行中断处理函数。
    • 第三个是程序主动中断,比如运行过程中需要申请其他资源,而主动让出控制权,重新调度。
    • 最后一个是创建一个新进程或新任务后主动发起的抢占式调度,新进程会默认创建一个main task, task的首条指令(入口函数)就是我们上层程序的main函数,它被放在代码段的第一的位置。
    • 哪些地方会申请调度?看一张图。

    这里提下图中的 OsCopyProcess(), 这是fork进程的主体函数,可以看出fork之后立即申请了一次调度。

    LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize)
    {
        UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES;
    
        if (flags & (~cloneFlag)) {
            PRINT_WARN("Clone dont support some flags!\n");
        }
    
        flags |= CLONE_FILES;
        return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize);
    }
    
    STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size)
    {
        UINT32 intSave, ret, processID;
        LosProcessCB *run = OsCurrProcessGet();//获取当前进程
    
        LosProcessCB *child = OsGetFreePCB();//从进程池中申请一个进程控制块,鸿蒙进程池默认64
        if (child == NULL) {
            return -LOS_EAGAIN;
        }
        processID = child->processID;
    
        ret = OsForkInitPCB(flags, child, name, sp, size);//初始化进程控制块
        if (ret != LOS_OK) {
            goto ERROR_INIT;
        }
    
        ret = OsCopyProcessResources(flags, child, run);//拷贝进程的资源,包括虚拟空间,文件,安全,IPC ==
        if (ret != LOS_OK) {
            goto ERROR_TASK;
        }
    
        ret = OsChildSetProcessGroupAndSched(child, run);//设置进程组和加入进程调度就绪队列
        if (ret != LOS_OK) {
            goto ERROR_TASK;
        }
    
        LOS_MpSchedule(OS_MP_CPU_ALL);//给各CPU发送准备接受调度信号
        if (OS_SCHEDULER_ACTIVE) {//当前CPU core处于活动状态
            LOS_Schedule();// 申请调度
        }
    
        return processID;
    
    ERROR_TASK:
        SCHEDULER_LOCK(intSave);
        (VOID)OsTaskDeleteUnsafe(OS_TCB_FROM_TID(child->threadGroupID), OS_PRO_EXIT_OK, intSave);
    ERROR_INIT:
        OsDeInitPCB(child);
        return -ret;
    }
    

    原来创建一个进程这么简单,真的就是在COPY!

    源码告诉你调度过程是怎样的

    以上是需要提前了解的信息,接下来直接上源码看调度过程吧,文件就三个函数,主要就是这个了:

    VOID OsSchedResched(VOID)
    {
        LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));//调度过程要上锁
        newTask = OsGetTopTask(); //获取最高优先级任务
        OsSchedSwitchProcess(runProcess, newProcess);//切换进程
        (VOID)OsTaskSwitchCheck(runTask, newTask);//任务检查
        OsCurrTaskSet((VOID*)newTask);//*设置当前任务
        if (OsProcessIsUserMode(newProcess)) {//判断是否为用户态,使用用户空间
            OsCurrUserTaskSet(newTask->userArea);//设置任务空间
        }
        /* do the task context switch */
        OsTaskSchedule(newTask, runTask); //切换CPU任务上下文,汇编代码实现
    }
    

    函数有点长,笔者留了最重要的几行,看这几行就够了,流程如下:

    1. 调度过程要自旋锁,多核情况下只能被一个CPU core 执行. 不允许任何中断发生, 没错,说的是任何事是不能去打断它,否则后果太严重了,这可是内核在切换进程和线程的操作啊。
    2. 在就绪队列里找个最高优先级的task
    3. 切换进程,就是task归属的那个进程设为运行进程,这里要注意,老的task和老进程只是让出了CPU指令执行权,其他都还在内存,资源也都没有释放.
    4. 设置新任务为当前任务
    5. 用户模式下需要设置task运行空间,因为每个task栈是不一样的.空间部分具体在系列篇内存中查看
    6. 是最重要的,切换任务上下文,参数是新老两个任务,一个要保存现场,一个要恢复现场。

    什么是任务上下文?看鸿蒙系统源码分析(总目录)其他文章,有专门的介绍。这里要说明的是 在CPU的层面,它只认任务上下文!这里看不到任何代码了,因为这是跟CPU相关的,不同的CPU需要去适配不同的汇编代码.

    请读懂内核最美函数 OsGetTopTask()

    最后留个作业,读懂这个笔者认为的内核最美函数,就明白了就绪队列是怎么回事了。这里提下goto语句,几乎所有内核代码都会大量的使用goto语句,鸿蒙内核有617个goto远大于264个break,还有人说要废掉goto,你知道内核开发者青睐goto的真正原因吗?

    LITE_OS_SEC_TEXT_MINOR LosTaskCB *OsGetTopTask(VOID)
    {
        UINT32 priority, processPriority;
        UINT32 bitmap;
        UINT32 processBitmap;
        LosTaskCB *newTask = NULL;
    #if (LOSCFG_KERNEL_SMP == YES)
        UINT32 cpuid = ArchCurrCpuid();
    #endif
        LosProcessCB *processCB = NULL;
        processBitmap = g_priQueueBitmap;
        while (processBitmap) {
            processPriority = CLZ(processBitmap);
            LOS_DL_LIST_FOR_EACH_ENTRY(processCB, &g_priQueueList[processPriority], LosProcessCB, pendList) {
                bitmap = processCB->threadScheduleMap;
                while (bitmap) {
                    priority = CLZ(bitmap);
                    LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &processCB->threadPriQueueList[priority], LosTaskCB, pendList) {
    #if (LOSCFG_KERNEL_SMP == YES)
                        if (newTask->cpuAffiMask & (1U << cpuid)) {
    #endif
                            newTask->taskStatus &= ~OS_TASK_STATUS_READY;
                            OsPriQueueDequeue(processCB->threadPriQueueList,
                                              &processCB->threadScheduleMap,
                                              &newTask->pendList);
                            OsDequeEmptySchedMap(processCB);
                            goto OUT;
    #if (LOSCFG_KERNEL_SMP == YES)
                        }
    #endif
                    }
                    bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1));
                }
            }
            processBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - processPriority - 1));
        }
    
    OUT:
        return newTask;
    }
    
    #ifdef __cplusplus
    #if __cplusplus
    }
    

    喜欢就关注下吧,您的关注真的很重要

    在这里插入图片描述

    作者邮箱:weharmony@126.com


    鸿蒙内核源码注释中文版 【 Gitee仓 | CSDN仓 | Github仓 | Coding仓 】精读内核源码,中文详细注解.深挖地基工程,构建底层网图.

    鸿蒙源码分析系列篇 【 CSDN | OSCHINA | HarmonyOS 】问答式导读, 生活式比喻, 图形化展示, 层层剥开内核神秘外衣.

    展开全文
  • Linux内核源码+查看工具,Linux内核源码+查看工具Linux内核源码+查看工具
  • linux内核源码,linux3版本内核源码,编写内核驱动参考的源代码,分析研究内核源码框架必备的工具
  • WIFI探针内核源码

    2017-09-22 14:13:15
    WIFI探针内核源码,通过解析wifi底层通讯协议,取得路由器附近的手机(sta设备)mac,openwrt操作系统。内核与应用层通讯使用genetlink
  • ubuntu命令安装内核源码   sudo apt-get install linux-source 会自动安装当前版本内核的源代码到 /usr/src   升级内核源码:  1.将下载过来linux源代码包(tar.bz2包)解压到/usr/src下。如果...
    ubuntu命令安装内核源码
     
    sudo apt-get install linux-source 会自动安装当前版本内核的源代码到 /usr/src
     
    升级内核源码:

      1.将下载过来linux源代码包(tar.bz2包)解压到/usr/src下。如果你还不知道怎么解压,请google之~解压完毕后可以在/usr/src目录下看到一个linux-2.6.31.6的文件夹

      2.转移目录至linux-2.6.31.6用如下命令:

      cd /usr/src/linux-2.6.31.6

      3.先配置Ubuntu内核:

      make menuconfig

      具体怎么配置我不清楚,不过这个基本上不用怎么配置的,直接选最后一项,save,exit就OK了

      4.接着开始编译Ubuntu内核:make

      这是一个漫长的过程,慢慢等吧~~这个花了我将近一个半小时的时间

      5.加入模块:

      make modules_install

      6.生成可执行的Ubuntu内核引导文件:

      make bzImage (注意i字母要大写)

      7.将bzImage复制至/boot下:

      cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.31.6 //2.6.32Ubuntu内核的bzImage目录为arch/x86/boot/bzImage

      8.清除多余的创建文件:

      make clean //这一步最好还是留到最后来做(现在可以先不跳过这一步),这样的话,即使你后面操作失误也可以回到这里重做,而不需要重新编译

      9.将System.map复制至/boot下:

      cp System.map /boot/System.map-2.6.31.6

      10.生成initrd.img 这个很重要,我开始弄错了这个,害的我白重启了一次。命令:

      cd /lib/modules/2.6.31.6

      sudo mkinitramfs -o /boot/initrd.img-2.6.31.6 //2.6.32可以为sudo update-initramfs -c - k 2.6.32

      11.自动查找新Ubuntu内核,并添加至grub引导:

      sudo update-grub

      这个过程也可以手动完成,方法是更改/boot/grub目录下menu.lst文件。这个文件引导系统的启动,结构很简单,就是指定引导文件而已,可以参考已有的启动项修改,我的是在该文件中添加如下内容:

      title Ubuntu 9.04, kernel 2.6.31

      uuid 753efade-04e8-4e2c-8bbb-965e9792b2f5

      kernel /boot/vmlinuz-2.6.31.6 root=UUID=753efade-04e8-4e2c-8bbb-965e9792b2f5 ro quiet splash

      initrd /boot/initrd.img-2.6.31.6

      //9.10采用的是Grub2 启动文件用grub.cfg代替 该文件所在目录为/boot/grub 若手动添加为可参考如下:

      menuentry "Ubuntu, Linux 2.6.32" {

      recordfail=1

      if [ -n ${have_grubenv} ]; then save_env recordfail; fi

      set quiet=1

      insmod ext2

      set root=(hd0,3)

      search --no-floppy --fs-uuid --set 3c611c5f-f941-4970-956f-fe4c7bf75714

      linux/boot/vmlinuz-2.6.32 root=UUID=3c611c5f-f941-4970-956f-fe4c7bf75714 ro quiet splash

      initrd/boot/initrd.img-2.6.32

      12.重启电脑:reboot 你会发现启动项里多了一个Ubuntu 9.04, kernel 2.6.31(Ubuntu, Linux 2.6.32)的选项,选择这个,进入系统。

      以上介绍Ubuntu内核更新。


    http://blog.chinaunix.net/uid-20672257-id-3239246.html

    展开全文
  • 作者结合UNIX V6已公开的相关文档,对UNIX V6的内核源码进行详细剖析,旨在让读者更深入地理解进程、中断、块I/O系统、文件系统、字符I/O系统、启动系统等操作系统的基本原理。 所需积分少,图文十分清晰
  • 内核源码部分

    2019-07-23 09:59:42
    今天想看一下具体的sendto的源码部分,但是即使是下载了内核源码也没有找到这个部分的内容;在网上查了一些资料。 文章[2]中对这部分进行了解释:glibc帮忙封装了sendto所以在内核中看到的,已经是经过经过封装的了...
    展开全文
  • Linux内核源码0.11版本

    2017-10-24 16:13:41
    完整的内核源码可以供个人学习Linux内核作为必不可少的资料使用
  • Aosp10内核源码下载

    千次阅读 2021-01-17 20:26:22
    AOSP内核源码组成 Android内核完整源码包括:内核源码,用于编译内核的所有工具,以及编译脚本build/build.sh用于构建内核使用。 其中,内核源代码中根目录下包括编译脚本build/build.sh。Android源码树仅包含预...
  • 其中包括linux内核源码最新下载地址(官方的),里面有一个网站下载操作文档,写得非常清楚,对于刚接触的linux系统内核的朋友很有帮助。
  • Linux内核源码

    2020-04-11 14:14:17
    linux内核源码网址: https://elixir.bootlin.com/linux/latest/source/net/ipv4/af_inet.c
  • Linux内核源码阅读以及工具(转)

    万次阅读 2018-09-21 01:04:33
    Linux内核源码阅读以及工具(转) 转载地址:Linux内核源码阅读以及工具(转)
  • linux内核1.0版本内核源码,免费大放送
  • linux内核源码结构

    万次阅读 2019-03-08 21:40:08
    linux内核源码结构 一、概述  Linux内核庞大,但是这些文件的结构还是有章可循的,分别位于不同的目录下,各个目录功能相对独立。 二、源码结构表 目录名 描述 arch 体系结构相关的代码,对于每个架构...
  • 详尽分析windows内核源码, 本文结合《Windows 内核情景分析》(毛德操著)、《软件调试》(张银奎著)、《Windows 核心编程》、《寒江独 钓-Windows 内核安全编程》、《Windows PE 权威指南》、《C++反汇编与逆向...
  • linux-3.10内核源码

    2018-03-29 17:17:17
    linux内核源码。3.10版本比较难找了,未经过修改,有需要的可以下载,不喜勿喷。
  • Linux epoll内核源码剖析

    千次阅读 2019-07-11 09:41:31
    poll Linux内核源码剖析 select Linux内核源码剖析 epoll Linux内核源码剖析 epoll Linux内核源码剖析 前面介绍了select/poll,此文章将讲解epoll,epoll是select/poll的增强版,epoll更加高效,当然也更加复杂 ...
  • linux 内核源码下载网址

    万次阅读 2018-04-25 10:28:06
    记录下linux 内核源码下载网址: https://mirrors.edge.kernel.org/pub/linux/kernel/
  • 编译Android系统源码和内核源码

    千次阅读 2018-11-11 10:41:44
    编译Android系统源码和内核源码
  • 1.鸿蒙内核源码分析(调度机制篇) 2.鸿蒙内核源码分析(进程管理篇) 3.鸿蒙内核源码分析(Task管理篇) 4.鸿蒙内核源码分析(内存管理篇) 5.鸿蒙内核源码分析(内存概念篇) 6.鸿蒙内核源码分析(内存映射篇) 7.鸿蒙内核...
  • Linux 4.4.0 内核源码分析 TCP实现 - Linux4.40版本的TCP/IP协议栈源码分析
  • linux内核源码的下载地址: https://mirrors.edge.kernel.org/pub/linux/kernel/ xilinx uboot源码下载地址: https://github.com/Xilinx/u-boot-xlnx xilinx 内核源码下载地址: ... ...
  • linux内核源码0.11版

    2013-11-29 00:28:31
    linux内核源码0.11,内附加完美注释文档。本人的经验:学习linux操作系统看内核源码是必不可少的步骤,而高版本的内核源码初学者则看起来则云里雾里,0.11版源码除网络外其它架构与高版本内核的代码的架构基本一致。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,813
精华内容 9,525
关键字:

内核源码