linux内核_linux内核编译 - CSDN
linux内核 订阅
Linux是一种开源电脑操作系统内核。它是一个用C语言写成,符合POSIX标准的类Unix操作系统。 [1]  Linux最早是由芬兰 Linus Torvalds为尝试在英特尔x86架构上提供自由的类Unix操作系统而开发的。该计划开始于1991年,在计划的早期有一些Minix 黑客提供了协助,而今天全球无数程序员正在为该计划无偿提供帮助。 展开全文
Linux是一种开源电脑操作系统内核。它是一个用C语言写成,符合POSIX标准的类Unix操作系统。 [1]  Linux最早是由芬兰 Linus Torvalds为尝试在英特尔x86架构上提供自由的类Unix操作系统而开发的。该计划开始于1991年,在计划的早期有一些Minix 黑客提供了协助,而今天全球无数程序员正在为该计划无偿提供帮助。
信息
软件授权
免费
软件名称
Linux内核
发明者
Linus Torvalds
使用时间
1991年
软件语言
C语言
Linux内核内核结构
操作系统是一个用来和硬件打交道并为用户程序提供一个有限服务集的低级支撑软件。一个计算机系统是一个硬件和软件的共生体,它们互相依赖,不可分割。计算机的硬件,含有外围设备、处理器、内存、硬盘和其他的电子设备组成计算机的发动机。但是没有软件来操作和控制它,自身是不能工作的。完成这个控制工作的软件就称为操作系统,在Linux的术语中被称为“内核”,也可以称为“核心”。Linux内核的主要模块(或组件)分以下几个部分:存储管理、CPU和进程管理、文件系统、设备管理和驱动、网络通信,以及系统的初始化(引导)、系统调用等。Linux内核使用三种不同的版本编号方式。  第一种方式用于1.0版本之前(包括1.0)。第一个版本是0.01,紧接着是0.02、0.03、0.10、0.11、0.12、0.95、0.96、0.97、0.98、0.99和之后的1.0。第二种方式用于1.0之后到2.6,数字由三部分“A.B.C”,A代表主版本号,B代表次主版本号,C代表较小的末版本号。只有在内核发生很大变化时(历史上只发生过两次,1994年的1.0,1996年的2.0),A才变化。可以通过数字B来判断Linux是否稳定,偶数的B代表稳定版,奇数的B代表开发版。C代表一些bug修复,安全更新,新特性和驱动的次数。以版本2.4.0为例,2代表主版本号,4代表次版本号,0代表改动较小的末版本号。在版本号中,序号的第二位为偶数的版本表明这是一个可以使用的稳定版本,如2.2.5,而序号的第二位为奇数的版本一般有一些新的东西加入,是个不一定很稳定的测试版本,如2.3.1。这样稳定版本来源于上一个测试版升级版本号,而一个稳定版本发展到完全成熟后就不再发展。第三种方式从2004年2.6.0版本开始,使用一种“time-based”的方式。3.0版本之前,是一种“A.B.C.D”的格式。七年里,前两个数字A.B即“2.6”保持不变,C随着新版本的发布而增加,D代表一些bug修复,安全更新,添加新特性和驱动的次数。3.0版本之后是“A.B.C”格式,B随着新版本的发布而增加,C代表一些bug修复,安全更新,新特性和驱动的次数。第三种方式中不再使用偶数代表稳定版,奇数代表开发版这样的命名方式。举个例子:3.7.0代表的不是开发版,而是稳定版!Linux最早是由芬兰人Linus Torvalds设计的。当时由于UNⅨ的 商业化,Andrew Tannebaum教授开发了Minix操作系统以便于不受AT&T许可协议的约束,为教学科研提供一个操作系统。当时发布在Internet上,免费给全世界的学生使用。Minix具有较多UNⅨ的特点,但与UNⅨ不完全兼容。1991年10月5日,Linus为了给Minix用户设计一个比较有效的UNⅨ PC版本,自己动手写了一个“类Minix”的操作系统。整个故事从两个在终端上打印AAAA...和BBBB...的进程开始的,当时最初的内核版本是0.02。Linus Torvalds将它发到了Minix新闻组,很快就得到了反应。Linus Torvalds在这种简单的任务切换机制上进行扩展,并在很多热心支持者的帮助下开发和推出了Linux的第一个稳定的工作版本。1991年11月,Linux0.10版本推出,0.11版本随后在1991年12月推出,当时将它发布在Internet上,免费供人们使用。当Linux非常接近于一种可靠的/稳定的系统时,Linus决定将0.13版本称为0.95版本。1994年3月,正式的Linux 1.0出现了,这差不多是一种正式的独立宣言。截至那时为止,它的用户基数已经发展得很大,而且Linux的核心开发队伍也建立起来了。在讨论大型而复杂的系统的体系结构时,可以从很多角度来审视系统。体系结构分析的一个目标是提供一种方法更好地理解源代码。Linux 内核实现了很多重要的体系结构属性。在或高或低的层次上,内核被划分为多个子系统。Linux 也可以看作是一个整体,因为它会将所有这些基本服务都集成到内核中。这与微内核的体系结构不同,后者会提供一些基本的服务,例如通信、I/O、内存和进程管理,更具体的服务都是插入到微内核层中的。随着时间的流逝,Linux 内核在内存和 CPU 使用方面具有较高的效率,并且非常稳定。但是对于 Linux 来说,最为有趣的是在这种大小和复杂性的前提下,依然具有良好的可移植性。Linux 编译后可在大量处理器和具有不同体系结构约束和需求的平台上运行。一个例子是 Linux 可以在一个具有内存管理单元(MMU)的处理器上运行,也可以在那些不提供MMU的处理器上运行。Linux 内核的uClinux移植提供了对非 MMU 的支持。核心的开发和规范一直是由Linux社区控制着,版本也是唯一的。实际上,操作系统的内核版本指的是在Linus本人领导下的开发小组开发出的系统内核的版本号。自1994年3月14日发布了第一个正式版本Linux 1.0以来,每隔一段时间就有新的版本或其修订版公布。Linux将标准的GNU许可协议改称Copyleft,以便与Copyright相对照。通用的公共许可(GPL)允许用户销售、拷贝和改变具有Copyleft的应用程序。当然这些程序也可以是Copyright的,但是你必须允许进一步的销售、拷贝和对其代码进行改变,同时也必须使他人可以免费得到修改后的源代码。事实证明,GPL对于Linux的成功起到了极大的作用。它启动了一个十分繁荣的商用Linux阶段,还为编程人员提供了一种凝聚力,诱使大家加入这个充满了慈善精神的Linux运动。
收起全文
精华内容
参与话题
  • Linux 内核编译(三天吐血经历!)

    万次阅读 多人点赞 2018-01-29 16:28:40
    前几天做一个实验:编译Linux内核并向其增加一个系统调用。这个实验实在是太让人无语了,各种坑!昨天这个时候,我还在苦苦煎熬中。在今天凌晨四点才做好。为了让其他人少走一些弯路,鄙人就把自己的经验以及教训写...
    写在前面的话:
    本人大二,东南大学一个软工狗,正在修一门名为《操作系统原理》的坑爹课!前几天做一个实验:编译Linux内核并向其增加一个系统调用。这个实验实在是太让人无语了,各种坑!昨天这个时候,我还在苦苦煎熬中。在今天凌晨四点才做好。为了让其他人少走一些弯路,鄙人就把自己的经验以及教训写下来。里面会有一些不足,希望大家多多指教~

    废话不多说,那就开始吧:

    一、实验前的准备:

    Vmware + ubuntu10.10 (32位)+ linux-2.6.32.71.tar.xz
    安装虚拟机教程:http://jingyan.baidu.com/article/90895e0f95a07564ec6b0bc7.html
    说明:ubuntu 10.10是我试验的最后一个,也是最后成功的那个。当然,更推荐ubuntu 10.04,因为这个支持sudo apt-update 少了一些麻烦。 而由于10.10不支持更新,故我另外新下了linux 2.6.32.71 先将这个文件拖入虚拟机桌面。

    附: ubuntu10.10百度网盘分享:链接:http://pan.baidu.com/s/1bnNr8dD 密码:ybg3
            linux-2.6.32.71.tar.xz 百度网盘分享:链接:http://pan.baidu.com/s/1c1cOOtq 密码:epu9(可能已经失效,大家可以去某度上面进行下载。网上资源很多,造成的不便,很抱歉~)

    二、解压内核

    1、先打开安装好的ubuntu 进入终端 :在桌面按ctrl+alt+T
    2、输入sudo su 获取root权限:(会出现一个输入密码的一个命令行,在终端输入密码时,是不显示星号的。你只管把密码输入回车就行了!用惯了window的小伙伴可能会有些不适应)最后如图:

    3、先把下载好的内核复制到 /usr/src 文件夹中 : 
          终端输入 cd Desktop(定位到桌面) 回车 ; cp  linux-2.6.32.71.tar.xz  /usr/src 回车
    4、解压内核 依次输入以下命令回车执行
          cd /usr/src ;
       xz -d linux-2.6.32.71.tar.xz

         tar xvf  linux-2.6.32.71.tar

    三、增加系统调用

    1、

    打开sys.c文件。

    gedit /usr/src/linux-2.6.32.71/kernel/sys.c

    2、

    在文件末尾增加系统调用。

    asmlinkage intsys_mycall(int number)

    {

     printk("My Student No. is XXXXX,and My Name is XXXXX*** !");

     return number;

    }

    注:printk就是系统调用输出一行文字,你可以自定义里面内容,便于最终检验。

    3、

     注册系统调用:

    gedit /usr/src/linux-2.6.32.71/arch/x86/kernel/syscall_table_32.S

    在.long 类型文件末尾添加:

    .longsys_mycall

    并且按照顺序记住它属于第几个系统调用,在本机中为337。

    4、

    gedit /usr/src/linux-2.6.32.71/arch/x86/include/asm/unistd_32.h

    在一系列#define __NR_之后添加:

     

    # define __NR_mycall 337

    在这里就需要用到之前记住的数字了。


    四、编译内核

    ps:深吸一口气,前面做的只是准备工作!下面才是真正的开始!打好精神,真正的挑战在下面!
    下面的记得一定要一步一步都要做!不要漏掉一步!!!!

    进入解压目录:

    cd /usr/src/linux-2.6.32.71

    make mrproper

    make clean

    make oldconfig

    make bzImage  (这个过程和下面的过程非常非常非常长,亲测,建议泡杯茶,或是看个电影,没有两个小时不行

    make modules

    make modules_install


    五、拷贝内核

    经过了漫长的等待,我们终于到了这一步。
    先检验一下我们的结果:

     


     首先查看一下编译好的内核版本,以便命名 打开 /lib/modules  里面应该多了一个纯数字不带"generic"的文件夹,那就是新内核版本号,我们的是2.62.32.71 如下所示:

    有了这个就代表前面的没有什么错误了。

    接着,就在终端输入: 

    cp /usr/src/linux-2.6.32.71/arch/i386/boot/bzImage  /boot/vmlinuz-2.6.32.71-mykernel


    六、创建initrd文件

    mkinitramfs-o /boot/initrd.img-2.6.32.71


    七、更新grub引导表

    进行到这一步,也许你感觉到自己差不多了,毕竟都这么久了,你也许有些困了,有些疲惫,但是,我告诉你,最难最容易出错的,就在当前这一步!建议你先休息一下,下面需要你投入百分之百的注意力去做,若是出错,你可是要全部重新开始的!
    1.

    gedit /boot/grub/grub.cfg


    2.
    在打开的文件中找到类似如下的字段,并复制并粘贴在前面:

    但必须在同一个

    ### BEGIN /etc/grub.d/10_linux ### 

           ……  

    ### END /etc/grub.d/10_linux ###

    里面

    字段如下:
    menuentry 'Ubuntu, with Linux 2.6.35-22-generic' --class ubuntu --class gnu-linux --class gnu --class os {
    recordfail
    insmod part_msdos
    insmod ext2
    set root='(hd0,msdos1)'
    search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9
    linux /boot/vmlinuz-2.6.35-22-generic root=UUID=0efd72ba-ba85-470f-8c21-ab68730ca8c9 ro   quiet splash
    initrd /boot/initrd.img-2.6.35-22-generic
    }
    menuentry 'Ubuntu, with Linux 2.6.35-22-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
    recordfail
    insmod part_msdos
    insmod ext2
    set root='(hd0,msdos1)'
    search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9
    echo 'Loading Linux 2.6.35-22-generic ...'
    linux /boot/vmlinuz-2.6.35-22-generic root=UUID=0efd72ba-ba85-470f-8c21-ab68730ca8c9 ro single 
    echo 'Loading initial ramdisk ...'
    initrd /boot/initrd.img-2.6.35-22-generic
    }


    将粘贴后字段里面的
     linux    /boot/vmlinuz-2.6.35-22-generic      initrd    /boot/initrd.img-2.6.35-22-generic  改成你的内核文件地址和initrd 地址:
     linux   /boot/vmlinuz-2.6.32.71-mykernel    initrd    /boot/initrd.img-2.6.32.71

    这一步特别无聊但又必须认认真真做,要不然你就前功尽弃,别问我怎么知道的,我要是牢记这句话,不会到四点才睡觉 ( ╯□╰ )!! 建议全部改完之后,检查几遍。笔者以及室友们都在这步出错,以至于不得不重新开始。全部完成如图所示:

     红框是改过之后的,篮框里面的是你需要复制的内容 可以看到 ,两者在同一个###BEGIN /etc/**** 里面 黄色下划线部分
    (图丑见谅)


    八、收尾工作

    好了,你若已经检查完毕上面的一切工作,那么,扫尾工作就开始了,这时候,也莫要放松 一步一步来,喝点开水,长呼口气,一步一步来,下面的一步一步落实:

    cd /boot

    cp initrd.img-2.6.32.71 initrd-2.6.32.71.old

    depmod–a

    update-initramfs-k 2.6.32.71 –c

    cd /tmp

    gzip-dc /boot/initrd.img-2.6.32.71| cpio –id

    touch lib/modules/2.6.32.71/modules.dep

    find./ | cpio -H newc -o > /boot/initrd.img-2.6.32.71.new

    gzip /boot/initrd.img-2.6.32.71.new

    cd /boot

    mvinitrd.img-2.6.32.71.new.gz initrd.img-2.6.32.71


    九、重启

    终于到了验证结果的一步了,此时你要克制一下自己的激动心情,在终端键入 reboot 点击回车。慢慢等待一会,若是你重启成功,那么恭喜你,你已经要看到胜利的曙光啦!
    重新进入终端,获取权限,过程前面有讲,不再重复。在终端键入 uname -a 回车
    此时若是看到

    linux-2.6.32.71,说明已经成功!

    如下:

    若是看到这个,你就可以大叫一声庆祝一下了,你已经成功啦!!!!

    十、测试自定义系统调用

    打开终端,键入gedit,打开gedit工具,继续键入如下代码:

    #include<stdio.h>

    int main()

    {

           syscall(337, 1);

           return 0;

    }

    保存为mytest.c

    再继续在终端中键入

    gcc-o mytest mytest.c(编译C程序)

    之后 ./mytest

    点击运行编译出来的程序,此时并不会显示出效果,在终端中键入dmesg –c查看系统调用信息。

    此时,你可以看到



    说明之前写的sys_mycall调用成功!
    到这一步,算是全部成功啦!!庆祝一下,去装个逼吧~~~~
     
    写在最后的话:

    由于笔者是新手,里面的步骤有些显得很笨重,希望大手们看到之后多多指教!谢谢!!
    另外,做这个实验一定要有耐心,若是你做的时候一直很小心,每一步都认真做,那么你一次就可以成功!!别像笔者这样做了不知多少遍。
    最后,祝大家成功!!   有不足,也希望大家指出,谢谢@~@
     
    ps:
    参考文档:http://wenku.baidu.com/view/40af3b6727d3240c8447efd8.html?qq-pf-to=pcqq.c2c

    第一篇博文,谢谢大家的浏览o(^▽^)o


    展开全文
  • linux内核移植步骤

    千次阅读 2018-12-11 13:17:45
    2016.6.8 经过一个多星期的内核...替换linux内核一共有两种方式,第一种方式是下载官方kernel提供的源码包,进行编译替换;第二种直接下载内核安装包deb,进行升级替换。 下面分别从这两种方式进行 一个说明: ...

    2016.6.8

    经过一个多星期的内核折磨,今天终于可以写下自己移植内核的一些心得,网上有很多博客论坛都有谈到,但是这些又说的方式有些模糊,这里我综合的几个博客在重新说下内核替换编译的步骤、以及如何更新启动项grub。替换linux的内核一共有两种方式,第一种方式是下载官方kernel提供的源码包,进行编译替换;第二种直接下载内核安装包deb,进行升级替换。

    下面分别从这两种方式进行 一个说明:

    方式一:kernel提供的源码包,进行编译替换

    1、首先做好内核编译前的准备工作,

    主要有两个准备工作,一是在linux kernel官网上下载源码包,二是安装好任意版本的linux Ubuntu 系统并下载相应的编译工具。

    在linux kernel上下载源码包,网址为:https://www.kernel.org/pub/linux/kernel/,选择对应的源码包下载,注意源码包的大小一般是几十兆左右,命名后缀为.tar.bz2,如下图所示:以linux_3.2.1为例子:
    在这里插入图片描述

    下载完成后,进行第二个准备工作,安装任意版本的Ubuntu,安装镜像网址:http://www.ubuntu.org.cn/download ,像装其他任意操作系统一样,安装完成Ubuntu操作系统,然后配置好联网,进行apk_get的下载。以下过程在root权限下进行,安装有关编译程序。安装make ,gcc, make-kpkg,运行menuconfig等等和编译内核相关的工具。

    有关命令:

    $sudo  apt-get install build-essential kernel-package   libncurses5-dev
    

    注意:
    (1)libncurses5-dev是为之后配置内核能运行 make menuconfig程序做准备
    Build-essential为编译工具,kernel-package是编译内核工具

    (2)如果系统显示无法查找到这三个文件,输入#apt-get update更新数据源。
    把刚刚下载的源码包进行拷贝在ubuntu系统中,并解压到/usr/src 目录下,解压可以直接右键解压,或者采用以下命令进行解压:

    $sudo tar Jvfx linux-3.4.88.tar.xz
    
    2、开始配置编译的相关文件及环境

    首先,清理以前编译时留下的临时文件。如果是刚刚解开的包,不需要执行这步。如果是第二次或者是第n次编译,那么一定要执行。
    相关命令如下:

    #$ sudo make mrproper
    

    然后将自己原本内核的配置文件拷贝过来成为新内核的配置文件,命令:

    #cp /boot/config-`uname -r` ./.config
    

    这里需要说明的是,拷贝过来是很方便的,相当于直接给新的内核编译提供对应的配置文件,告诉内核哪些文件要编译,哪些不需要编译,但是经过几次的编译修改,这一部分是可以自定义的,利用我们之前下载的工具menuconfig。

    进入内核的源码目录

    #cd /usr/src/linux_3.2.1
    

    执行以下命令:

    #make  menuconfig
    

    注意:这个命令需要在超级用户权限下执行,否则可能会报出一些莫名奇妙的错误。执行这个命令之后了,就可一看到下面的图片了:
    在这里插入图片描述
    这个图里面就可以对配置文件进行一个修改了,如果当初直接拷贝原内核的配置文件,那么此时直接选择倒数第二行load an Alternate Configuration File,然后sava即可。

    如果自己配置则选择上面的任意目录,进行选择哪些文件要编译,哪些不编译,一般需要选择的是设备驱动,选项是Device Drivers,选择完毕后同样保存save即可。

    注意这两种方式都可以,看用户自己的选择。具体的每个选项的内容解析见一下博客:
    http://forum.ubuntu.org.cn/viewtopic.php?t=134404

    3、开始编译新内核

    编译命令:

    #make all -j4
    

    执行以上命令之后就可以编译内核了,
    make all就是将内核以及模块一起编译。后面的参数-j4表示,cpu要开启四个线程来编译内核。一般来说,每个cpu可以开启两个线程来编译内核,我的电脑是有两个cpu,所以开启了4个线程。这样编译真心很快的,以前没有发现这样编译,只有一个线程编译真心够等好长时间的。

    4、编译完成之后,就可以进行内核的安装了

    我们将源代码目录下的arch/x86_64/boot/bzImage复制到/boot/下面,因为我下载的源代码版本为linux-3.2.1,但是需要根据自己的cpu类型,如是x86架构还是amd,或者是32位或64位,在相应的目录下寻找bzImage。
    所以复制的命令为:

    #cp arch/x86_64/boot/bzImage /boot/vmlinuz-3.2.1  
    

    这里需要说明,bzImage必须得有,是编译成功完成的一个生成文件,如果没有此文件,对不起,编译失败,请重新回去编译。vmlinuz-3.2.1 是自己主动命令的,可以自己改,但一般都是这种命令方式。

    5、将源代码目录下的System.map复制到/boot目录下:

    命令:

    #cp /usr/src/linux-3.2.1/System.map System.map-3.2.1
    
    6、.将源代码目录下的.config复制到/boot/目录下:

    命令:

    #cp .config /boot/config-3.2.1
    
    7、安装模块

    命令:

    #make modules_install
    
    8、生成initrd.img文件
    #cd /lib/modules/3.2.1
    #update-initramfs –c –k 3.2.1
    
    9、.切换到/boot/grub/目录下,自动查找新内核,并添加至grub引导
    #update-grub
    
    10、修改开机grub启动时间间隔,命令如下:
    #cd /ect/default
    #sudo nano ./grub
    

    将hidden两行代码注释掉,这样开机启动的grub就会出现,可以由你选择改启动哪个内核版本。

    #GRUB_HIDDEN_TIMEOUT=0 
    #GRUB_HIDDEN_TIMEOUT_QUIET=true
    

    更改完成之后,在重新生成grub.cfg文件,命令和上面一样:

    #update-grub
    
    11、切换至grub.cfg目录

    以文本形式查看,是否更新有新内核的启动项,如果有即可不用修改,如果没有,进行手动修改。

    #cd /boot/grub
    #sudo nano ./grub.cfg
    

    手动修改,按照原来内核的格式进行修改,只用修改新内核的名字而已。

    12、重启电脑,在previous version中选择启动新编译的内核,成功进入系统。

    输入内核版本检测命令:

    命令:#uname -r
    

    就会出现新内核的名称!!!恭喜,替换内核成功!

    方式二:下载内核安装包deb,进行升级替换

    首先必须说明的是,这种方式我尝试了两台电脑,两个不同的内核升级,均为成功,原因不详:
    具体步骤简单如下:

    1.下载deb包

    http://kernel.ubuntu.com/~kernel-ppa/mainline/ 上下载所需升级包。此处下载的是64位的3.5.4版本的3个deb包:

    linux-headers-3.5.4-030504_3.5.4-030504.201209142010_all.deb
    linux-headers-3.5.4-030504-generic_3.5.4-030504.201209142010_amd64.deb
    linux-image-3.5.4-030504-generic_3.5.4-030504.201209142010_amd64.deb
    
    2.安装deb包

    首先安装架构无关的即带all的headers包

    sudo dpkg -i linux-headers-3.5.4-030504_3.5.4-030504.201209142010_all.deb
    sudo dpkg -i linux-headers-3.5.4-030504-generic_3.5.4-030504.201209142010_amd64.deb
    sudo dpkg -i linux-image-3.5.4-030504-generic_3.5.4-030504.201209142010_amd64.deb
    

    安装后,/boot目录下会生成新的内核的相关文件,/lib/modules目下也生成了相应模块。

    3.更新启动项grub

    按照上述的步骤9开始,与上面一样。更新完了grub.cfg,然后重新启动,进行新的内核即可
    测试按照这种步骤进行,但是开机进入之后直接紫屏,没有任何现象,原因不明!!!

    展开全文
  • linux1.0内核代码学习(一)

    千次阅读 2019-03-21 17:01:50
    库文件和头文件 在程序中,使用#include <stdio.h>类似的头文件stdio.h在编译器的头文件路径中,#include "abc.h"中的abc.h文件则应该在当前目录。通过对编译器指定参数-I<PATH>来指定头文件所在目录...

    库文件和头文件

        在程序中,使用#include <stdio.h>类似的头文件stdio.h在编译器的头文件路径中,#include "abc.h"中的abc.h文件则应该在当前目录。通过对编译器指定参数-I<PATH>来指定头文件所在目录,可以用 #include <>来引用。例如:gcc -I./include hello.c,将从当前目录下的include目录下去寻找头文件。

        同理,程序中调用的库函数在编译时也需要指定路径,同时指定库。使用-L<PATH>参数指定库文件的目录,-l<FILE>指定包含的库文件。例如,要使用libXXX.so库,参数为-lXXX。

        一般一个库编译完成后有库文件和头文件。如果要使用这个库,可以将库文件目录和头文件目录分别用-I和-L参数指定,也可以将他们拷贝到编译器的include和lib目录下。

     

    编译之前先到https://www.kernel.org/pub/linux/kernel/下载linux 1.0的源代码

    一、编译linux1.0内核代码

    虚拟机:fedora10 32位 内核版本2.6.27.41-170.2.117.fc10.i686

    编译环境:gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC) 

    1、拷贝linux-1.0.tar.gz到我的工作目录:/mnt/mywork,解压tar zxvf linux-1.0.tar.gz,修改目录名字:mv linux linux-1.0,

    进入到工作目录/mnt/mywork设置gcc编译时的默认环境变量,gcc默认的头文件目录为/usr/include,为了不破坏虚拟机本来的编译环境,因此在编译linux1.0内核的时候在控制台中设置gcc环境变量 C_INCLUDE_PATH=/mnt/mywork/linux-1.0/include/,或者在Makefile中添加gcc环境变量C_INCLUDE_PATH =/mnt/mywork/linux-1.0/include/;同时修改Makefile中变量KERNELHDRS =/usr/src/linux/include为KERNELHDRS =/mnt/mywork/linux-1.0/include/

    2、配置内核

    [root@localhost linux-1.0]# make config

    /bin/sh Configure  < config.in

    *

    * General setup

    *

    Kernel math emulation (CONFIG_MATH_EMULATION) [y] 

    Normal harddisk support (CONFIG_BLK_DEV_HD) [y] 

    XT harddisk support (CONFIG_BLK_DEV_XD) [n] 

    TCP/IP networking (CONFIG_INET) [y] 

    Limit memory to low 16MB (CONFIG_MAX_16M) [n] 

    System V IPC (CONFIG_SYSVIPC) [y] 

    Use -m486 flag for 486-specific optimizations (CONFIG_M486) [y] 

    *

    * Program binary formats

    *

    Elf executables (CONFIG_BINFMT_ELF) [y] 

    COFF executables (CONFIG_BINFMT_COFF) [y] 

    *

    * SCSI support

    *

    SCSI support? (CONFIG_SCSI) [n] 

    :

    : Skipping SCSI configuration options...

    :

    *

    * Network device support

    *

    Network device support? (CONFIG_ETHERCARDS) [y] 

    SLIP (serial line) support (CONFIG_SLIP) [n] 

    PLIP (parallel port) support (CONFIG_PLIP) [n] 

    NE2000/NE1000 support (CONFIG_NE2000) [n] 

    WD80*3 support (CONFIG_WD80x3) [y] 

    SMC Ultra support (CONFIG_ULTRA) [n] 

    3c501 support (CONFIG_EL1) [n] 

    3c503 support (CONFIG_EL2) [n] 

    3c509/3c579 support (CONFIG_EL3) [n] 

    HP PCLAN support (CONFIG_HPLAN) [n] 

    AT1500 and NE2100 (LANCE and PCnet-ISA) support (CONFIG_LANCE) [n] 

    AT1700 support (CONFIG_AT1700) [n] 

    DEPCA support (CONFIG_DEPCA) [n] 

    D-Link DE600 pocket adaptor support (CONFIG_DE600) [n] 

    AT-LAN-TEC/RealTek pocket adaptor support (CONFIG_ATP) [n] y

    *

    Sony CDU31A CDROM driver support (CONFIG_CDU31A) [n] 

    Mitsumi CDROM driver support (CONFIG_MCD) [n] 

    Matsushita/Panasonic CDROM driver support (CONFIG_SBPCD) [n] 

    *

    * Filesystems

    *

    Standard (minix) fs support (CONFIG_MINIX_FS) [y] 

    Extended fs support (CONFIG_EXT_FS) [n] 

    Second extended fs support (CONFIG_EXT2_FS) [y] 

    xiafs filesystem support (CONFIG_XIA_FS) [n] 

    msdos fs support (CONFIG_MSDOS_FS) [y] 

    /proc filesystem support (CONFIG_PROC_FS) [y] 

    NFS filesystem support (CONFIG_NFS_FS) [y] 

    ISO9660 cdrom filesystem support (CONFIG_ISO9660_FS) [n] 

    OS/2 HPFS filesystem support (read only) (CONFIG_HPFS_FS) [n] 

    System V and Coherent filesystem support (CONFIG_SYSV_FS) [n] 

    *

    *  character devices

    *

    Parallel printer support (CONFIG_PRINTER) [n] 

    Logitech busmouse support (CONFIG_BUSMOUSE) [n] 

    PS/2 mouse (aka "auxiliary device") support (CONFIG_PSMOUSE) [y] 

    C&T 82C710 mouse port support (as on TI Travelmate) (CONFIG_82C710_MOUSE) [y] 

    Microsoft busmouse support (CONFIG_MS_BUSMOUSE) [n] 

    ATIXL busmouse support (CONFIG_ATIXL_BUSMOUSE) [n] 

    Selection (cut and paste for virtual consoles) (CONFIG_SELECTION) [n] 

    QIC-02 tape support (CONFIG_TAPE_QIC02) [n] 

    QIC-117 tape support (CONFIG_FTAPE) [n] 

    *

    * Sound

    *

    Sound card support (CONFIG_SOUND) [n] 

    *

    * Kernel hacking

    *

    Kernel profiling support (CONFIG_PROFILE) [n] 

     

    The linux kernel is now hopefully configured for your setup.

    Check the top-level Makefile for additional configuration,

    and do a 'make dep ; make clean' if you want to be sure all

    the files are correctly re-made

     

    mv .tmpconfig .config

    3、编译内核前准备make dep

    [root@localhost linux-1.0]# make dep

    serial.c:538:8: error: macro names must be identifiers(错误:宏名必须是标识符)

    make[2]: *** [dep] Error 1

    make[2]: Leaving directory `/mnt/mywork/linux-1.0/drivers/char'

    make[1]: *** [dep] Error 2

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/drivers'

    make: *** [dep] Error 2

    解决办法:

    serial.c的第538行,修改为这样

    //#ifdef 0

    #if 0

    [root@localhost linux-1.0]# make dep

    buffer.c:108:8: error: macro names must be identifiers

    make[1]: *** [dep] Error 1

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'

    make: *** [dep] Error 2

    解决办法:

    buffer.c的第108行,修改为这样

    //#ifdef 0

    #if 0

    [root@localhost linux-1.0]# make dep

    touch tools/version.h

    for i in init/*.c;do echo -n "init/";gcc -D__KERNEL__ -E -M $i;done > .tmpdepend

    for i in tools/*.c;do echo -n "tools/";gcc -D__KERNEL__ -E -M $i;done >> .tmpdepend

    set -e; for i in kernel drivers mm fs net ipc ibcs lib; do make -C $i dep; done

    make[1]: Entering directory `/mnt/mywork/linux-1.0/kernel'

    gcc -D__KERNEL__ -E -M *.c > .depend

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/kernel'

    make[1]: Entering directory `/mnt/mywork/linux-1.0/drivers'

    set -e; for i in block char net FPU-emu; do make -C $i dep; done

    make[2]: Entering directory `/mnt/mywork/linux-1.0/drivers/block'

    ...................................................................................................................

    gcc -D__KERNEL__ -E -M *.c > .depend

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/lib'

    rm -f tools/version.h

    mv .tmpdepend .depend

    可以看到现在make dep成功。

     

    linux1.0内核代码学习(一) - 北极星 - xiebingsuccess的博客

     在编译bootsect.s的时候出现上面的错误,是因为as86不能找到宏定义 DEF_SYSSIZE、DEF_INITSEG等,这是由于bootsect.s中包含#include <linux/config.h>头文件,在gcc的时候应该包含到命令行中,比如makefile中CC =gcc -D__KERNEL__ -I$(TOPDIR)/include,这样as86就能识别出变量定义SYSSIZE = DEF_SYSSIZE等

    4、[root@localhost linux-1.0]# make zImage

    gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA  boot/bootsect.S -o boot/bootsect.s

    as86 -0 -a -o boot/bootsect.o boot/bootsect.s

    make: as86: Command not found

    make: *** [boot/bootsect.o] Error 127

    在确保网络连通的情况下进行as86的安装:

    [root@localhost linux-1.0]# yum install dev86*

    Loaded plugins: refresh-packagekit

    Setting up Install Process

    Resolving Dependencies

    --> Running transaction check

    ---> Package dev86.i386 0:0.16.17-10.fc10 set to be updated

    --> Finished Dependency Resolution

     

    Dependencies Resolved

     

    =================================================================================

     Package         Arch           Version                   Repository        Size

    =================================================================================

    Installing:

     dev86           i386           0.16.17-10.fc10           fedora           374 k

     

    Transaction Summary

    =================================================================================

    Install       1 Package(s)

    Upgrade       0 Package(s)

     

    Total download size: 374 k

    Is this ok [y/N]: y

    Downloading Packages:

    dev86-0.16.17-10.fc10.i386.rpm                            | 374 kB     00:00     

    Running rpm_check_debug

    Running Transaction Test

    Finished Transaction Test

    Transaction Test Succeeded

    Running Transaction

      Installing     : dev86-0.16.17-10.fc10.i386                                1/1 

     

    Installed:

      dev86.i386 0:0.16.17-10.fc10                                                   

     

    Complete!

    [root@localhost linux-1.0]# make zImage

    as86 -0 -a -o boot/bootsect.o boot/bootsect.s

    ld86 -0 -s -o boot/bootsect boot/bootsect.o

    gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA  boot/setup.S -o boot/setup.s

    as86 -0 -a -o boot/setup.o boot/setup.s

    ld86 -0 -s -o boot/setup boot/setup.o

    gcc -D__KERNEL__ -E -traditional boot/head.S -o boot/head.s

    as -c -o boot/head.o boot/head.s

    as: unrecognized option '-c'

    make: *** [boot/head.o] Error 1

    出错原因:as 语法和1991年的时候有了一些变化。

    解决办法:在Makefile中将$(AS) -c -o $*.o $< 修改为 $(AS) -o $*.o $<  

    [root@localhost linux-1.0]# make zImage

    gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA  boot/bootsect.S -o boot/bootsect.s

    as86 -0 -a -o boot/bootsect.o boot/bootsect.s

    ld86 -0 -s -o boot/bootsect boot/bootsect.o

    gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA  boot/setup.S -o boot/setup.s

    as86 -0 -a -o boot/setup.o boot/setup.s

    ld86 -0 -s -o boot/setup boot/setup.o

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -m486  -c -o init/main.o init/main.c

    cc1: error: unrecognized command line option "-m486"

    make: *** [init/main.o] Error 1

    出错原因:gcc 3.4 或者更高版本,已经去除了"-m486"和"-m386"

    解决办法:在Makefile注释掉下面语句:

    ##ifdef CONFIG_M486

    #CFLAGS := $(CFLAGS) -m486

    ##else

    #CFLAGS := $(CFLAGS) -m386

    ##endif

    或者修改为

    ifdef CONFIG_M486

    CFLAGS := $(CFLAGS) -march=i486

    else

    CFLAGS := $(CFLAGS) -march=i386

    endif

    [root@localhost linux-1.0]# make zImage

    /mnt/mywork/linux-1.0/include/linux/string.h:130: error: can't find a register in class ‘SIREG’ while reloading ‘asm’

    /mnt/mywork/linux-1.0/include/linux/string.h:130: error: ‘asm’ operand has impossible constraints

    make: *** [init/main.o] Error 1

    这两个错误都是由于C嵌入汇编用法不对造成的,后续make的时候还会遇到非常多的相同的错误,更改方法都一样。参见下面的引用进行修改:

    linux1.0内核代码学习 - 北极星 - xiebingsuccess的博客

     

    [root@localhost linux-1.0]# make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe  -c -o init/main.o init/main.c

    init/main.c:58: warning: conflicting types for built-in function ‘_exit’

    init/main.c:96:8: warning: extra tokens at end of #endif directive

    init/main.c: In function ‘get_options’:

    init/main.c:159: warning: array subscript has type ‘char’

    init/main.c:206:8: warning: extra tokens at end of #endif directive

     

    init/main.c:58:warning: conflicting types for built-in function ‘_exit’这是由于58处定义的int _exit(int exitcode)函数与内置的void _exit(int exitcode)函数定义不一样导致的。更改时可以重新定义一个无返回值的宏,删去原来定义_exit的宏然后用这个无返回值的宏再定义_exit函数。源码定义中修改如下:

    在include\linux\unistd.h中,重新定义宏

    #define _syscall_exit(type,name,atype,a) \  

    type name(atype a) \    

    { \  

     long __res; \  

    __asm__ volatile ("int $0x80" \  

         : "=a" (__res) \  

         : "0" (__NR_##name),"b" ((long)(a))); \   

    }  

    init/main.c:58中修改如下:

    //static inline _syscall1(int,_exit,int,exitcode)

    static inline _syscall_exit(void,_exit,int,exitcode)

     

    这两个警告init/main.c:96:8: warning: extra tokens at end of #endif directive

    init/main.c:206:8: warning: extra tokens at end of #endif directive是因为在#endif后面跟了一个宏,只要删掉 每一个#endif后面的宏就可以了。

     

    警告nit/main.c: In function ‘get_options’:

    init/main.c:159: warning: array subscript has type ‘char’这是由于传入参数不匹配导致,将isdigit()的参数强制转换成int即可。while (cur && isdigit((int)*cur) && i <= 10)

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe  -fno-omit-frame-pointer -c sched.c

    In file included from sched.c:35:

    /mnt/mywork/linux-1.0/include/linux/timex.h:120: error: conflicting type qualifiers for ‘xtime’

    /mnt/mywork/linux-1.0/include/linux/sched.h:308: error: previous declaration of ‘xtime’ was here

    sched.c:41: error: conflicting type qualifiers for ‘xtime’

    /mnt/mywork/linux-1.0/include/linux/sched.h:308: error: previous declaration of ‘xtime’ was here

    make[1]: *** [sched.o] Error 1

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/kernel'

    make: *** [linuxsubdirs] Error 2

    解决办法:

    修改/include/linux/sched.h第308行,修改为这样

    //extern struct timeval xtime;

    extern volatile struct timeval xtime;

    保持和/include/linux/timex.h中的xtime声明一致

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe  -fno-omit-frame-pointer -c sched.c

    sched.c: Assembler messages:

    sched.c:289: Warning: indirect ljmp without `*'

    gcc -D__KERNEL__ -E -traditional sys_call.S -o sys_call.s

    as -c -o sys_call.o sys_call.s

    as: unrecognized option '-c'

    make[1]: *** [sys_call.o] Error 1

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/kernel'

    make: *** [linuxsubdirs] Error 2

    解决方法,修改kernel目录下的Makefile文件如下:

    .s.o:

    $(AS) -o $*.o $<

    #$(AS) -c -o $*.o $<

     

    [root@localhost linux-1.0]# make clean;make zImage

    fpu_entry.c:473: error: lvalue required as left operand of assignment

    fpu_entry.c:474:8: warning: extra tokens at end of #endif directive

    fpu_entry.c:528: warning: dereferencing type-punned pointer will break strict-aliasing rules

    fpu_entry.c:529:8: warning: extra tokens at end of #endif directive

    fpu_entry.c:537:8: warning: extra tokens at end of #endif directive

    fpu_entry.c:548: warning: dereferencing type-punned pointer will break strict-aliasing rules

    fpu_entry.c:649:8: warning: extra tokens at end of #endif directive

    make[2]: *** [fpu_entry.o] Error 1

    make[2]: Leaving directory `/mnt/mywork/linux-1.0/drivers/FPU-emu'

    解决办法:

    文件/linux/drivers/FPU-emu/fpu_system.h中

    第64行,修改为这样

    //#define FPU_data_address        ((void *)(I387.soft.twd))

    #define FPU_data_address        ((I387.soft.twd))

    文件/include/linux/sched.h中

    第117行的,修改为这样

    struct i387_soft_struct {

            long    cwd;

            long    swd;

            //long  twd;

            void*   twd;

            long    fip;

            long    fcs;

            long    foo;

            long    fos;

            long    top;

            struct fpu_reg  regs[8];        /* 8*16 bytes for each FP-reg = 128 bytes */

            unsigned char   lookahead;

            struct info     *info;

            unsigned long   entry_eip;

    };

     

    [root@localhost linux-1.0]# make clean;make zImage

    fpu_trig.c: In function ‘rem_kernel’:

    fpu_trig.c:748: error: missing terminating " character

    fpu_trig.c:749: error: expected string literal before ‘movl’

    fpu_trig.c:750:56: warning: missing terminating " character

    fpu_trig.c:750: error: missing terminating " character

    解决办法:

    文件/linux/drivers/FPU-emu/fpu_trig.c中

    第748行,

      /* Do the required multiplication and subtraction in the one operation */

      asm volatile ("movl %2,%%eax; mull %4; subl %%eax,%0; sbbl %%edx,%1;

                     movl %3,%%eax; mull %4; subl %%eax,%1;

                     movl %2,%%eax; mull %5; subl %%eax,%1;"

                    :"=m" (x), "=m" (((unsigned *)&x)[1])

                    :"m" (st1),"m" (((unsigned *)&st1)[1]),

                     "m" (q),"m" (((unsigned *)&q)[1])

                    :"%ax","%dx");

      修改为这样             

      asm volatile ("movl %2,%%eax; mull %4; subl %%eax,%0; sbbl %%edx,%1;"

                    "movl %3,%%eax; mull %4; subl %%eax,%1;"

                    "movl %2,%%eax; mull %5; subl %%eax,%1;"

                    :"=m" (x), "=m" (((unsigned *)&x)[1])

                    :"m" (st1),"m" (((unsigned *)&st1)[1]),

                     "m" (q),"m" (((unsigned *)&q)[1])

                    :"%ax","%dx");   

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c exec.c

    exec.c: In function ‘copy_strings’:

    exec.c:381: error: lvalue required as left operand of assignment

    make[1]: *** [exec.o] Error 1

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'

    make: *** [linuxsubdirs] Error 2

    解决办法:

    vi /usr/src/linux/fs/exec.c

    第380行,修改为这样

    if (!(pag = (char *) page[p/PAGE_SIZE]) &&

        !(pag = (char *) (page[p/PAGE_SIZE] = (unsigned long *) get_free_page(GFP_USER))))

        //!(pag = (char *) page[p/PAGE_SIZE] = (unsigned long *) get_free_page(GFP_USER)))

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c balloc.c

    balloc.c:51:10: warning: missing terminating " character

    balloc.c: In function ‘find_first_zero_bit’:

    balloc.c:51: error: missing terminating " character

    balloc.c:52: error: expected string literal before ‘cld’

    balloc.c:55:6: error: invalid suffix "f" on integer constant

    balloc.c:60:7: error: invalid suffix "f" on integer constant

    balloc.c:64:19: warning: missing terminating " character

    balloc.c:64: error: missing terminating " character

    balloc.c:81:11: warning: missing terminating " character

    balloc.c: In function ‘find_next_zero_bit’:

    balloc.c:81: error: missing terminating " character

    balloc.c:82: error: expected string literal before ‘bsfl’

    balloc.c:83:8: error: invalid suffix "f" on integer constant

    balloc.c:85:6: warning: missing terminating " character

    balloc.c:85: error: missing terminating " character

    balloc.c:106:10: warning: missing terminating " character

    balloc.c: In function ‘find_first_zero_byte’:

    balloc.c:106: error: missing terminating " character

    balloc.c:107: error: expected string literal before ‘cld’

    balloc.c:110:7: error: invalid suffix "f" on integer constant

    balloc.c:112:5: warning: missing terminating " character

    balloc.c:112: error: missing terminating " character

    make[2]: *** [balloc.o] Error 1

    make[2]: Leaving directory `/mnt/mywork/linux-1.0/fs/ext2'

    make[1]: *** [filesystems.a] Error 2

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'

    make: *** [linuxsubdirs] Error 2

    解决办法:

    在/linux/fs/ext2/balloc.c 中

    第51行,修改为这样

            __asm__("cld\n\t" \

                    "movl $-1,%%eax\n\t" \

                    "repe;\n\t" \

                    "scasl\n\t" \

                    "je 1f\n\t" \

                    "subl $4,%%edi\n\t" \

                    "movl (%%edi),%%eax\n\t" \

                    "notl %%eax\n\t" \

                    "bsfl %%eax,%%edx\n\t" \

                    "jmp 2f\n\t" \

    "1:             xorl %%edx,%%edx\n\t" \

    "2:             subl %%ebx,%%edi\n\t" \

                    "shll $3,%%edi\n\t" \

                    "addl %%edi,%%edx" \

                    :"=d" (res)

                    :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)

                    );

                    //:"ax", "bx", "cx", "di");

    第81行,修改为这样

      __asm__("bsfl %1,%0\n\t" \

                "jne 1f\n\t" \

                "movl $32, %0\n\t" \

                "1:                     " \

                : "=r" (set)

                : "r" (~(*p >> bit)));  

    第106行,修改为这样

            __asm__("cld\n\t" \

                    "mov $0,%%eax\n\t" \

                    "repnz; scasb\n\t" \

                    "jnz 1f\n\t" \

                    "dec %%edi\n\t" \

                    "1:             " \

                    : "=D" (res)

                    : "0" (addr), "c" (size)

                    );

                    //: "ax");

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c ialloc.c

    ialloc.c:42:10: warning: missing terminating " character

    ialloc.c: In function ‘find_first_zero_bit’:

    ialloc.c:42: error: missing terminating " character

    ialloc.c:43: error: expected string literal before ‘cld’

    ialloc.c:46:6: error: invalid suffix "f" on integer constant

    ialloc.c:51:7: error: invalid suffix "f" on integer constant

    ialloc.c:55:19: warning: missing terminating " character

    ialloc.c:55: error: missing terminating " character

    make[2]: *** [ialloc.o] Error 1

    make[2]: Leaving directory `/mnt/mywork/linux-1.0/fs/ext2'

    make[1]: *** [filesystems.a] Error 2

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'

    make: *** [linuxsubdirs] Error 2

    解决办法:

    在文件/linux/fs/ext2/ialloc.c中

    第42行,修改为这样

     __asm__("cld\n\t" \

      "movl $-1,%%eax\n\t" \

      "repe; scasl\n\t" \

      "je 1f\n\t" \

      "subl $4,%%edi\n\t" \

      "movl (%%edi),%%eax\n\t" \

      "notl %%eax\n\t" \

      "bsfl %%eax,%%edx\n\t" \

      "jmp 2f\n\t" \

    "1:  xorl %%edx,%%edx\n\t" \

    "2:  subl %%ebx,%%edi\n\t" \

      "shll $3,%%edi\n\t" \

      "addl %%edi,%%edx" \

      : "=d" (res)

      : "c" ((size + 31) >> 5), "D" (addr), "b" (addr)

      );

      //: "ax", "bx", "cx", "di");

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c inode.c

    inode.c: In function ‘ext2_alloc_block’:

    inode.c:110: error: can't find a register in class ‘CREG’ while reloading ‘asm’

    inode.c:110: error: ‘asm’ operand has impossible constraints

    make[2]: *** [inode.o] Error 1

    make[2]: Leaving directory `/mnt/mywork/linux-1.0/fs/ext2'

    make[1]: *** [filesystems.a] Error 2

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'

    make: *** [linuxsubdirs] Error 2

    解决办法:

    在/mnt/mywork/linux/fs/ext2/inode.c 文件中

    第28行修改为如下所示:

    #define clear_block(addr,size) \

    __asm__("cld\n\t" \

    "rep\n\t" \

    "stosl" \

    : \

    :"a" (0), "c" (size / 4), "D" ((long) (addr)) \

    )//:"cx", "di"

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe \

    -c -o sock.o sock.c

    sock.c: In function ‘unix_proto_create’:

    sock.c:331: error: lvalue required as left operand of assignment

    sock.c: In function ‘unix_proto_release’:

    sock.c:363: error: lvalue required as left operand of assignment( 错误:赋值运算的左操作数必须是左值)

    make[2]: *** [sock.o] Error 1

    make[2]: Leaving directory `/mnt/mywork/linux-1.0/net/unix'

    make[1]: *** [subdirs] Error 2

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/net'

    make: *** [linuxsubdirs] Error 2

    解决办法:

    vi /mnt/mywork/linux/net/unix/sock.c

    第331行,修改为这样

    //UN_DATA(sock) = upd;

    sock->data = upd;

    第363行,修改为这样

    //UN_DATA(sock) = NULL;

    sock->data = NULL;

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c -o arp.o arp.c

    arp.c:126: error: conflicting type qualifiers for ‘arp_q’

    arp.h:48: error: previous declaration of ‘arp_q’ was here

    make[2]: *** [arp.o] Error 1

    make[2]: Leaving directory `/mnt/mywork/linux-1.0/net/inet'

    make[1]: *** [subdirs] Error 2

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/net'

    make: *** [linuxsubdirs] Error 2

    解决办法:

    vi /mnt/mywork/linux/net/inet/arp.h

    第48行,修改为这样

    //extern struct sk_buff *arp_q;

    extern struct sk_buff * volatile arp_q;

    保持和arp.c中的定义一致

     

    [root@localhost linux-1.0]# make clean;make zImage

    fs/fs.o:(.text+0x6391): more undefined references to `gdt' follow

    net/net.o: In function `loopback_xmit':

    loopback.c:(.text+0x74a7): undefined reference to `_intr_count'

    loopback.c:(.text+0x74af): undefined reference to `_bh_active'

    loopback.c:(.text+0x74b5): undefined reference to `_bh_mask'

    loopback.c:(.text+0x74bd): undefined reference to `_intr_count'

    loopback.c:(.text+0x74c2): undefined reference to `_do_bottom_half'

    loopback.c:(.text+0x74c8): undefined reference to `_intr_count'

    drivers/block/block.a(floppy.o): In function `floppy_ready':

    floppy.c:(.text+0xf48): undefined reference to `floppy_track_buffer'

    floppy.c:(.text+0x10e2): undefined reference to `tmp_floppy_area'

    floppy.c:(.text+0x113e): undefined reference to `tmp_floppy_area'

    drivers/block/block.a(floppy.o): In function `redo_fd_request':

    floppy.c:(.text+0x13d9): undefined reference to `floppy_track_buffer'

    floppy.c:(.text+0x157a): undefined reference to `tmp_floppy_area'

    floppy.c:(.text+0x1583): undefined reference to `tmp_floppy_area'

    floppy.c:(.text+0x1590): undefined reference to `tmp_floppy_area'

    floppy.c:(.text+0x159b): undefined reference to `tmp_floppy_area'

    drivers/block/block.a(floppy.o): In function `setup_rw_floppy':

    floppy.c:(.text+0x17b3): undefined reference to `floppy_track_buffer'

    floppy.c:(.text+0x18d8): undefined reference to `tmp_floppy_area'

    floppy.c:(.text+0x193e): undefined reference to `tmp_floppy_area'

    drivers/block/block.a(floppy.o): In function `rw_interrupt':

    floppy.c:(.text+0x2293): undefined reference to `floppy_track_buffer'

    floppy.c:(.text+0x233d): undefined reference to `tmp_floppy_area'

    drivers/char/char.a(console.o): In function `scrup':

    console.c:(.text+0xb39): undefined reference to `_video_num_columns'

    console.c:(.text+0xbbb): undefined reference to `_video_num_columns'

    drivers/char/char.a(console.o): In function `con_write':

    console.c:(.text+0x26a1): undefined reference to `_video_num_columns'

    console.c:(.text+0x2c20): undefined reference to `_video_num_columns'

    drivers/char/char.a(keyboard.o): In function `hard_reset_now':

    keyboard.c:(.text+0x344): undefined reference to `pg0'

    keyboard.c:(.text+0x368): undefined reference to `_no_idt'

    make: *** [tools/zSystem] Error 1

    大量类似这样的问题

    解决办法:

     

    vi boot/head.S

    .globl _idt,_gdt,

    .globl _swapper_pg_dir,_pg0

    .globl _empty_bad_page

    .globl _empty_bad_page_table

    .globl _empty_zero_page

    .globl _tmp_floppy_area,_floppy_track_buffer

    修改为

    .globl idt,gdt,

    .globl swapper_pg_dir,pg0

    .globl empty_bad_page

    .globl empty_bad_page_table

    .globl empty_zero_page

    .globl tmp_floppy_area,floppy_track_buffer

     

    并且把标志为由"_"下划线开头的去掉下划线, 这是由as汇编器进化导致的问题.

     

    vi kernel/sys_call.S

    vi kernel/ksyms.S

    vi kernel/ksyms.sh

    vi drivers/FPU-emu/div_small.S

    vi drivers/FPU-emu/polynomial.S

    vi drivers/FPU-emu/poly_div.S

    vi drivers/FPU-emu/poly_mul64.S 

    vi drivers/FPU-emu/reg_div.S

    vi drivers/FPU-emu/reg_norm.S

    vi drivers/FPU-emu/reg_round.S

    vi drivers/FPU-emu/reg_u_add.S

    vi drivers/FPU-emu/reg_u_div.S

    vi drivers/FPU-emu/reg_u_mul.S

    vi drivers/FPU-emu/reg_u_sub.S

    vi drivers/FPU-emu/wm_shrx.S

    vi drivers/FPU-emu/wm_sqrt.S

    vi net/inet/loopback.c loopback_xmit里相关__asm__的内容

    vi drivers/char/keyboard.c  hard_reset_now里相关__asm__的内容

    vi drivers/char/console.c  scrup里相关__asm__的内容; scrdown里相关__asm__的内容

    vi usr/include/linux/sched.h switch_to里相关__asm__的内容_current修改为current

    vi usr/src/linux/include/asm/irq.h 里相关__asm__的内容

    vi drivers/FPU-emu/fpu_asm.h 

    #define EXCEPTION _exception

    修改为

    #define EXCEPTION exception

     

    [root@localhost linux-1.0]# make clean;make zImage

    kernel/kernel.o: In function `symbol_table':

    (.data+0xed0): undefined reference to `verify_write'

    make: *** [tools/zSystem] Error 1

    解决办法:

    vi  /mnt/mywork/linux-1.0/include/linux/mm.h

    修改

    //int __verify_write(unsigned long addr, unsigned long count);

    extern int verify_write(unsigned long addr, unsigned long count);

     

    extern inline int verify_area(int type, const void * addr, unsigned long size)

    {

     if (TASK_SIZE <= (unsigned long) addr)

      return -EFAULT;

     if (size > TASK_SIZE - (unsigned long) addr)

      return -EFAULT;

     if (wp_works_ok || type == VERIFY_READ || !size)

      return 0;

     //return __verify_write((unsigned long) addr,size);

     return verify_write((unsigned long) addr,size);

    }

     

    vi /mnt/mywork/linux-1.0/mm/memcpy.c

    第654行,修改为这样

    //int __verify_write(unsigned long start, unsigned long size)

    int verify_write(unsigned long start, unsigned long size)

    {

     size--;

     size += start & ~PAGE_MASK;

     size >>= PAGE_SHIFT;

     start &= PAGE_MASK;

     do {

      do_wp_page(1,start,current,0);

      start += PAGE_SIZE;

     } while (size--);

     return 0;

    }

     

    [root@localhost linux-1.0]# make clean;make zImage

    gcc -D__KERNEL__ -O2 -DSTDC_HEADERS  -c -o misc.o misc.c

    misc.c:81: error: conflicting types for ‘malloc’

    misc.c:113: warning: conflicting types for built-in function ‘puts’

    make[1]: *** [misc.o] Error 1

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'

    make: *** [zBoot/zSystem] Error 2

    解决办法:

    vi /mnt/mywork/linux-1.0/zBoot/misc.c

    第81行,修改为这样

    //void *malloc(int size)

    void *malloc(size_t size)

     

    [root@localhost linux-1.0]# make clean;make zImage

    ld  -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o

    ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000

    misc.o: In function `fill_inbuf':

    misc.c:(.text+0x42c): undefined reference to `input_len'

    misc.c:(.text+0x470): undefined reference to `input_data'

    misc.c:(.text+0x47c): undefined reference to `input_data'

    make[1]: *** [zSystem] Error 1

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'

    make: *** [zBoot/zSystem] Error 2

    解决办法:

    vi /mnt/mywork/linux-1.0/zBoot/misc.c

    第53行,修改为这样 

    //extern char input_data[];

    char input_data[];

    //extern int input_len;

    int input_len;

     

    [root@localhost linux-1.0]# make clean;make zImage

    ld  -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o

    ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'

    gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -o tools/build tools/build.c

    tools/build boot/bootsect boot/setup zBoot/zSystem CURRENT > zImage

    Root device is (-3, 0)

    Boot sector 512 bytes.

    Setup is 1980 bytes.

    Non-GCC header of 'system'

    make: *** [zImage] Error 1

    解决办法:

    vi /mnt/mywork/linux-1.0/tools/build.c

    第191行,修改为这样

    //if (N_MAGIC(*ex) != ZMAGIC)

    //      die("Non-GCC header of 'system'");

     

    [root@localhost linux-1.0]# make clean;make zImage

    ld  -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o

    ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'

    gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -o tools/build tools/build.c

    tools/build boot/bootsect boot/setup zBoot/zSystem CURRENT > zImage

    Root device is (-3, 0)

    Boot sector 512 bytes.

    Setup is 1980 bytes.

    System is 64 kB (64 kB code, 0 kB data and 0 kB bss)

    Unexpected EOF

    Can't read 'system'

    make: *** [zImage] Error 1

    解决办法:

    vi /mnt/mywork/linux-1.0/tools/build.c

    第208行,修改为这样

    n=read(id, buf, l);

    if (n != l) {

            if( n < 0)

            {

                    perror(argv[1]);

                    fprintf(stderr, "Unexpected EOF\n");

                    die("Can't read 'system'");

            }

            else if( n == 0)

                    break;

    }

    if (write(1, buf, n) != n)

            die("Write failed");

    sz -= n;

     

    最后编译成功:

    gcc -D__KERNEL__ -E -traditional head.S -o head.s

    as -o head.o head.s

    #as -c -o head.o head.s

    gcc -D__KERNEL__ -O2 -DSTDC_HEADERS  -c -o inflate.o inflate.c

    gcc -D__KERNEL__ -O2 -DSTDC_HEADERS  -c -o unzip.o unzip.c

    gcc -D__KERNEL__ -O2 -DSTDC_HEADERS  -c -o misc.o misc.c

    misc.c:54: warning: array ‘input_data’ assumed to have one element

    ld  -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o

    ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000

    make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'

    gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -o tools/build tools/build.c

    tools/build boot/bootsect boot/setup zBoot/zSystem CURRENT > zImage

    Root device is (-3, 0)

    Boot sector 512 bytes.

    Setup is 1980 bytes.

    System is 64 kB (64 kB code, 0 kB data and 0 kB bss)

    sync

    [root@localhost linux-1.0]# ls

    boot        Configure  fs       ipc       makever.sh  tools

    CHANGES     COPYING    ibcs     kernel    mm          zBoot

    config.in   CREDITS    include  lib       net         zImage

    config.old  drivers    init     Makefile  README      zSystem.map

    [root@localhost linux-1.0]# 

     

     

    对于ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000错误的解决方法是修改两个地方:

    vi /linux-1.0/boot/head.S

    在文件开始出添加:

    .globl startup_32

    vi /linux-1.0/Makefile第203行修改为:

    tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs

    $(LD) $(LDFLAGS) -e startup_32 -Ttext 100000 boot/head.o init/main.o tools/version.o

     

    vi /linux-1.0/zboot/head.s

    在文件开始出添加

    .globl startup_32

    vi /linux-1.0/zBoot/Makefile第22行修改为:

    zSystem: piggy.o $(zOBJECTS)

    $(LD) $(LDFLAGS) -o zSystem -e startup_32 -Ttext 1000 $(zOBJECTS) piggy.o

    展开全文
  • Linux的用户空间与内核空间

    万次阅读 2018-09-03 10:51:23
    Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间。两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在...

    一. 简介

    • Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间。两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。用户空间的内存映射采用段页式,而内核空间有自己的规则;本文旨在探讨内核空间的地址映射。
    • os分配给每个进程一个独立的、连续的、虚拟的地址内存空间,该大小一般是4G(32位操作系统,即2的32次方),其中将高地址值的内存空间分配给os占用,linux os占用1G,window os占用2G;其余内存地址空间分配给进程使用。

     

    • 通常32位Linux内核虚拟地址空间划分0~3G为用户空间,3~4G为内核空间(注意,内核可以使用的线性地址只有1G)。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。

     

     

    • 进程寻址空间0~4G
    • 进程在用户态只能访问0~3G,只有进入内核态才能访问3G~4G  
    • 进程通过系统调用进入内核态
    • 每个进程虚拟空间的3G~4G部分是相同的  
    • 进程从用户态进入内核态不会引起CR3的改变但会引起堆栈的改变

     

    二. Linux内核高端内存

    1. 由来

    当内核模块代码或线程访问内存时,代码中的内存地址都为逻辑地址,而对应到真正的物理内存地址,需要地址一对一的映射,如逻辑地址0xc0000003对应的物理地址为0×3,0xc0000004对应的物理地址为0×4,… …,逻辑地址与物理地址对应的关系为

    物理地址 = 逻辑地址 – 0xC0000000:这是内核地址空间的地址转换关系,注意内核的虚拟地址在“高端”,但是ta映射的物理内存地址在低端。

    逻辑地址 物理内存地址
    0xc0000000 0×0
    0xc0000001 0×1
    0xc0000002 0×2
    0xc0000003 0×3
    0xe0000000 0×20000000
    0xffffffff 0×40000000 ??

    假 设按照上述简单的地址映射关系,那么内核逻辑地址空间访问为0xc0000000 ~ 0xffffffff,那么对应的物理内存范围就为0×0 ~ 0×40000000,即只能访问1G物理内存。若机器中安装8G物理内存,那么内核就只能访问前1G物理内存,后面7G物理内存将会无法访问,因为内核 的地址空间已经全部映射到物理内存地址范围0×0 ~ 0×40000000。即使安装了8G物理内存,那么物理地址为0×40000001的内存,内核该怎么去访问呢?代码中必须要有内存逻辑地址 的,0xc0000000 ~ 0xffffffff的地址空间已经被用完了,所以无法访问物理地址0×40000000以后的内存。

    显 然不能将内核地址空间0xc0000000 ~ 0xfffffff全部用来简单的地址映射。因此x86架构中将内核地址空间划分三部分:ZONE_DMA、ZONE_NORMAL和 ZONE_HIGHMEM。ZONE_HIGHMEM即为高端内存,这就是内存高端内存概念的由来。


    在x86结构中,三种类型的区域(从3G开始计算)如下:

    ZONE_DMA        内存开始的16MB

    ZONE_NORMAL       16MB~896MB

    ZONE_HIGHMEM       896MB ~ 结束(1G)

     

    2. 理解

    前 面我们解释了高端内存的由来。 Linux将内核地址空间划分为三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端内存HIGH_MEM地址空间范围为 0xF8000000 ~ 0xFFFFFFFF(896MB~1024MB)。那么如内核是如何借助128MB高端内存地址空间是如何实现访问可以所有物理内存

    当内核想访问高于896MB物理地址内存时,从0xF8000000 ~ 0xFFFFFFFF地址空间范围内找一段相应大小空闲的逻辑地址空间,借用一会。借用这段逻辑地址空间,建立映射到想访问的那段物理内存(即填充内核PTE页面表),临时用一会,用完后归还。这样别人也可以借用这段地址空间访问其他物理内存,实现了使用有限的地址空间,访问所有所有物理内存。如下图。

    例 如内核想访问2G开始的一段大小为1MB的物理内存,即物理地址范围为0×80000000 ~ 0x800FFFFF。访问之前先找到一段1MB大小的空闲地址空间,假设找到的空闲地址空间为0xF8700000 ~ 0xF87FFFFF,用这1MB的逻辑地址空间映射到物理地址空间0×80000000 ~ 0x800FFFFF的内存。映射关系如下:

    逻辑地址 物理内存地址
    0xF8700000 0×80000000
    0xF8700001 0×80000001
    0xF8700002 0×80000002
    0xF87FFFFF 0x800FFFFF

    当内核访问完0×80000000 ~ 0x800FFFFF物理内存后,就将0xF8700000 ~ 0xF87FFFFF内核线性空间释放。这样其他进程或代码也可以使用0xF8700000 ~ 0xF87FFFFF这段地址访问其他物理内存。

    从上面的描述,我们可以知道高端内存的最基本思想:借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存。

    看到这里,不禁有人会问:万一有内核进程或模块一直占用某段逻辑地址空间不释放,怎么办?若真的出现的这种情况,则内核的高端内存地址空间越来越紧张,若都被占用不释放,则没有建立映射到物理内存都无法访问了。

     

    3. 划分

    内核将高端内存划分为3部分:VMALLOC_START~VMALLOC_END、KMAP_BASE~FIXADDR_START和FIXADDR_START~4G。


    对 于高端内存,可以通过 alloc_page() 或者其它函数获得对应的 page,但是要想访问实际物理内存,还得把 page 转为线性地址才行(为什么?想想 MMU 是如何访问物理内存的),也就是说,我们需要为高端内存对应的 page 找一个线性空间,这个过程称为高端内存映射。

    对应高端内存的3部分,高端内存映射有三种方式:
    映射到”内核动态映射空间”(noncontiguous memory allocation)
    这种方式很简单,因为通过 vmalloc() ,在”内核动态映射空间”申请内存的时候,就可能从高端内存获得页面(参看 vmalloc 的实现),因此说高端内存有可能映射到”内核动态映射空间”中。

    持久内核映射(permanent kernel mapping)
    如果是通过 alloc_page() 获得了高端内存对应的 page,如何给它找个线性空间?
    内核专门为此留出一块线性空间,从 PKMAP_BASE 到 FIXADDR_START ,用于映射高端内存。在 2.6内核上,这个地址范围是 4G-8M 到 4G-4M 之间。这个空间起叫”内核永久映射空间”或者”永久内核映射空间”。这个空间和其它空间使用同样的页目录表,对于内核来说,就是 swapper_pg_dir,对普通进程来说,通过 CR3 寄存器指向。通常情况下,这个空间是 4M 大小,因此仅仅需要一个页表即可,内核通过来 pkmap_page_table 寻找这个页表。通过 kmap(),可以把一个 page 映射到这个空间来。由于这个空间是 4M 大小,最多能同时映射 1024 个 page。因此,对于不使用的的 page,及应该时从这个空间释放掉(也就是解除映射关系),通过 kunmap() ,可以把一个 page 对应的线性地址从这个空间释放出来。

    临时映射(temporary kernel mapping)
    内核在 FIXADDR_START 到 FIXADDR_TOP 之间保留了一些线性空间用于特殊需求。这个空间称为”固定映射空间”在这个空间中,有一部分用于高端内存的临时映射。

    这块空间具有如下特点:
    (1)每个 CPU 占用一块空间
    (2)在每个 CPU 占用的那块空间中,又分为多个小空间,每个小空间大小是 1 个 page,每个小空间用于一个目的,这些目的定义在 kmap_types.h 中的 km_type 中。

    当要进行一次临时映射的时候,需要指定映射的目的,根据映射目的,可以找到对应的小空间,然后把这个空间的地址作为映射地址。这意味着一次临时映射会导致以前的映射被覆盖。通过 kmap_atomic() 可实现临时映射。

     

    三. 其他

    1、用户空间(进程)是否有高端内存概念?

    用户进程没有高端内存概念。只有在内核空间才存在高端内存。用户进程最多只可以访问3G物理内存,而内核进程可以访问所有物理内存。

    2、64位内核中有高端内存吗?

    目前现实中,64位Linux内核不存在高端内存,因为64位内核可以支持超过512GB内存。若机器安装的物理内存超过内核地址空间范围,就会存在高端内存。

    3、用户进程能访问多少物理内存?内核代码能访问多少物理内存?

    32位系统用户进程最大可以访问3GB,内核代码可以访问所有物理内存。

    64位系统用户进程最大可以访问超过512GB,内核代码可以访问所有物理内存。

    4、高端内存和物理地址、逻辑地址、线性地址的关系?

    高端内存只和逻辑地址有关系,和逻辑地址、物理地址没有直接关系。

     

    转自:

    linux 用户空间与内核空间——高端内存详解

    bug fixed 系列之二 : 进程内存空间分布情况

    展开全文
  • Linux更新内核

    千次阅读 2019-03-26 11:00:44
    Linux 内核分两种:官方内核(通常是内核开发人员用)和各大 Linux 发行版内核(一般用户常用)。 1.1 官方内核 在使用 Docker 时,发现其对 Linux 内核版本的最低要求是 3.10(这也刚好是 CentOS 7.2...
  • 3---Linux内核及内核编程

    千次阅读 2018-12-21 10:59:06
    什么是操作系统? 指在系统中负责完成最基本功能和系统管理的部分, 操作系统有哪些组成部分?...Linux内核源代码目录结构是什么,各目录有什么含义? arch:包含和硬件体系结构相关的代码,每种平台占一...
  • Linux内核的整体架构简介

    万次阅读 多人点赞 2017-10-23 17:46:51
    本文是“Linux内核分析”系列文章的第一篇,会以内核的核心功能为出发点,描述Linux内核的整体架构,以及架构之下主要的软件子系统。之后,会介绍Linux内核源文件的目录结构,并和各个软件子系统对应。 注:本文和...
  • Linux内核简介

    万次阅读 多人点赞 2018-06-16 18:56:29
    大纲:理解Linux内核最好预备的知识点Linux内核的特点Linux内核的任务内核的组成部分哪些地方用到了内核机制?Linux进程 Linux创建新进程的机制Linux线程 内核线程地址空间与特权级别 虚拟地址与物理地址 特权级别...
  • Linux内核组成部分(一)

    千次阅读 2019-01-11 10:31:38
    内核的任务 在纯技术层面上,内核是硬件与软件之间的一个中间层。其作用是将应用程序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址 从应用程序的视角来看,内核可以被认为是一台增强的...
  • 查看Linux内核版本命令

    万次阅读 2020-08-17 16:35:55
    1.umane -a 2.cat /proc/version 3.lsb_release -a
  • Linux内核源码阅读以及工具(转)

    万次阅读 2020-01-21 18:26:01
    Linux内核源码阅读以及工具(转) 转载地址:Linux内核源码阅读以及工具(转)
  • 查看Linux内核版本的命令

    万次阅读 2008-08-07 22:23:00
    方法一: 命令: uname -a作用: 查看系统内核版本号及系统名称方法二:命令: cat /proc/version作用: 查看目录"/proc"下version的信息,也可以得到当前系统的内核版本号及系统名称补充说明: /proc文件系统,它...
  • 如何查看linux内核版本

    万次阅读 2018-04-09 09:50:56
    第一种:登录linux,在终端输入 cat /proc/version 运行效果如下图: 第二种:登录linux,在终端输入 uname -a 即列出linux内核版本号 运行效果如下图: 第三种:在Linux终端输入 unmae -a 即可查看linux的...
  • Linux内核下载地址(官方网站)

    万次阅读 2018-03-10 09:25:38
    https://www.kernel.org/pub/linux/kernel/
  • Linux升级内核的正确姿势

    万次阅读 热门讨论 2018-08-21 11:26:10
    Linux升级内核的正确姿势 很多童鞋在玩耍linux发行版的时候,都会遇到各种各样的问题,比如:网卡不能使用,亮度不能调节,触摸板不能识别...Linux内核最早是于1991年由芬兰黑客林纳斯·托瓦兹为自己的个人计算机开...
  • linux内核源码下载地址

    万次阅读 多人点赞 2018-08-25 22:36:38
    官网链接: https://www.kernel.org/ HTTP ... GIT ... 官网下载经常速度太慢,无法下载,提供另一个链接: http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/ 可以根据需要,下...
  • 删除Ubuntu中不用的内核

    万次阅读 2018-03-20 19:42:37
    最近在学习Linux相关的知识,免不了查看Linux源代码和修改源代码,并且编译Linux内核。下面简单介绍一下如何删除Ubuntu中不用的内核。1、查看Linux中当前使用的内核:使用 uname -a 或者 uname -r 命令2、查看Linux...
  • Linux内核学习笔记(1)—— 什么是Linux内核? 1. 什么是操作系统? 操作系统是负责完成整个系统中最基本功能和系统管理,包括内核、设备驱动程序、启动引导程序、命令行shell或其它种类的用户界面、基本的文件...
  • Linux各版本内核下载地址

    千次阅读 2018-12-16 23:19:17
    Linux内核下载地址 https://cdn.kernel.org/pub/linux/kernel/
  • Linux内核国内镜像下载地址

    万次阅读 2019-08-02 17:15:44
    http://mirror.bjtu.edu.cn/kernel/linux/kernel/ 苦于官方网站的访问速度,这里记录一下。
1 2 3 4 5 ... 20
收藏数 671,815
精华内容 268,726
关键字:

linux内核