分析Linux 0.11中的kernel部分的makefile文件



#
# 在UltraEdit下注释

#

#
# if you want the ram-disk device, define this to be the
# size in blocks.
#
RAMDISK = #-DRAMDISK=512

#
#8086汇编编译器和连接器. -0生成8086目标程序;-a生成与gas和gld部分兼容的代码???zzz
#
AS86 =as86 -0 -a 
LD86 =ld86 -0

#
#GNU汇编编译器和连接器
#
AS =gas   
LD =gld

#
#GNU连接器gld运行时用到的选项
#-s 输出文件中省略所有的符号信息
#-x 删除所有的局部符号
#-M 在标准输出设备(显示器)上打印连接映象(link map).
#连接映象:由连接程序产生的一种内存地址映象,其中列出了程序装入到内存中的位置信息,具体有如下信息:
#目标文件及符号信息映射到内存中的位置
#公共符号如何放置
#连接中包含的所有文件成员及其引用的符号
#
LDFLAGS =-s -x -M

#
#gcc是GNU C程序编译器,对于UNIX类的脚本程序而言,
#在引用定义的标识符时,需在前面加上$符号并用括号括住标识符
#
CC =gcc $(RAMDISK)

#
#GCC的选项.
#-Wall 打印所有的警告信息
#-O 对代码进行优化
#-fstrength-reduce 优化循环语句
#-msting-insns Linus在学习gcc编译器时为gcc增加的选项,
 #用于gcc-1.40在复制结构等操作时使用386CPU的字符串指令,可以去掉
#
CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer \
-fcombine-regs -mstring-insns

#
#CPP是gcc的预处理程序
#-nostdinc -Iinclude 不要搜索标准的头文件目录中的文件,
#而是使用-I选项指定的目录或者是在当前的目录里搜索头文件
#
CPP =cpp -nostdinc -Iinclude

#
# ROOT_DEV specifies the default root-device when making the image.
# ROOT_DEV 指定在创建内核映象文件时所使用的默认根文件系统所在的设备
# This can be either FLOPPY, /dev/xxxx or empty, in which case the
# default of /dev/hd6 is used by ‘build‘.
#
ROOT_DEV=/dev/hd6

#
# kernel 目录,mm目录,fs目录所产生的目标代码文件。
# 为了方便引用,在这里将它们用ARCHIVES(归档文件) 标识符表示
#
ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o

#
# 块和字符设备库文件
# .a表示该文档是个归档文档,也即包含有许多可执行二进制代码子程序集合的库文件,通常是用GNU的ar程序生成。
# ar是GNU的二进制文件处理程序,用于创建、修改以及从归档文件中抽取文件
#
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a

#
# 数学运算库文件
#
MATH =kernel/math/math.a

#
# 由lib/目录中生成的通用库文件
#
LIBS =lib/lib.a

#
# make老式的隐式后缀规则
# 指示make利用下面的命令将所有的.c文件编译生成.s汇编程序
# ‘:‘表示下面是该规则的命令
#
.c.s:
#
# 指使gcc采用前面CFLAGS所指定的选项以及仅使用include/目录中的头文件,
# 在适当的编译后不进行汇编就停止(-S),从而产生与输入的各个C文件对应的汇编语言形式的代码文件。
# 默认情况下所产生的汇编程序文件是原C文件名去掉.c而加上.s后缀。
# -o表示其后是输出文件的形式。
# 其中$*.s(或[email protected])是自动目标变量,$<代表第一个先决条件,这里即是符合条件*.c的文件。
#
 $(CC) $(CFLAGS) \
 -nostdinc -Iinclude -S -o $*.s $<
#
# 将所有.s汇编程序文件编译成.o目标文件。下一条是实现该操作的具体命令
#
.s.o:
#
# 使用gas编译器将汇编程序编译成.o目标文件。-c表示只编译或汇编,但不进行连接操作
#
 $(AS) -c -o $*.o $<
.c.o:
#
# 使用gcc将c语言编译成目标文件但不连接
#
 $(CC) $(CFLAGS) \
 -nostdinc -Iinclude -c -o $*.o $<

#
# all表示创建Makefile所知的最顶层目标。这里即是image文件
#
all: Image

#
# 第一行说明:目标文件(Image文件)是由分号后面的4个元素产生
# 下面两行是执行的命令
# 第一行表示使用tools目录下的build工具程序将bootsect,setup,system文件以$(ROOT_DEV)为根文件系统设备组装成内核映象文件Image
# 第二行的sysn同步命令是迫使缓冲块数据立即写盘并更新超级块
#
Image: boot/bootsect boot/setup tools/system tools/build
 tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image
 sync

#
# 表明disk这个目标要由Image产生
# dd为UNIX标准命令:复制一个文件,根据选项进行转换和格式化
# bs=表示一次读/写的字节数,if=表示输入的文件.of=表示输出到的文件
# /dev/PS0指第一个软盘驱动器(设备文件)
#这个可以改成/dev/fd0,,编译完之后执行make disk直接把image文件插入到fd0里边,重新执行之后就会显示编译完的内容

#为什么这里的/dev/PS0不行,尚不清楚
disk: Image
 dd bs=8192 if=Image of=/dev/PS0

tools/build: tools/build.c
 $(CC) $(CFLAGS) \
 -o tools/build tools/build.c

#
# 利用上面的.s.o规则生成head.o文件
#
boot/head.o: boot/head.s

#
# 最后的>System.map表示gld需要将连接映象重定向存放在System.map文件中
#
tools/system: boot/head.o init/main.o \
  $(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS)
 $(LD) $(LDFLAGS) boot/head.o init/main.o \
 $(ARCHIVES) \
 $(DRIVERS) \
 $(MATH) \
 $(LIBS) \
 -o tools/system > System.map

#
# 数学协处理函数文件math.a由下一行上的命令实现
# 进入kernel/math/目录,运行make工具程序
#
kernel/math/math.a:
 (cd kernel/math; make)

#
# 块设备函数文件 blk_drv.a
#
kernel/blk_drv/blk_drv.a:
 (cd kernel/blk_drv; make)

#
# 字符备函数文件 chr_drv.a
#
kernel/chr_drv/chr_drv.a:
 (cd kernel/chr_drv; make)

#
# 内核目标模块kernel.o
#
kernel/kernel.o:
 (cd kernel; make)

#
# 内核管理模块mm.o
#
mm/mm.o:
 (cd mm; make)

#
# 文件系统目标模块fs.o
#
fs/fs.o:
 (cd fs; make)

#
# 库函数lib.a
#
lib/lib.a:
 (cd lib; make)

#
# 用8086汇编和连接器对setup.s文件进行编译生成setup文件
# -s表示要取出目标文件中的符号信息
#
boot/setup: boot/setup.s
 $(AS86) -o boot/setup.o boot/setup.s
 $(LD86) -s -o boot/setup boot/setup.o

#
# 生成bootsect.o磁盘引导块
#
boot/bootsect: boot/bootsect.s
 $(AS86) -o boot/bootsect.o boot/bootsect.s
 $(LD86) -s -o boot/bootsect boot/bootsect.o

#
# 在bootsect.s程序开口添加一行有关system文件长度信息
# 首先生成含有 "SYSSIZE = 文件实际长度"一行信息的tmp.s文件,然后将bootsect.s文件添加在其后。
# 取得system长度的方法是:
 # 利用ls命令对system文件进行长列表显示
 # 用grep命令取得列表上文件字节数字段信息,并定向保存在tmp.s临时文件中
 # cut命令用于剪切字符串
 # tr用于去除行尾的回车符
 # (实际长度 + 15)/16用于获得‘节‘表示的长度信息,1节=16字节
#
tmp.s: boot/bootsect.s tools/system
 (echo -n "SYSSIZE = (";ls -l tools/system | grep system \
  | cut -c25-31 | tr ‘\012‘ ‘ ‘; echo "+ 15 ) / 16") > tmp.s
 cat boot/bootsect.s >> tmp.s

#
# 当执行"make clean"时,就会执行以下命令,去除所有编译连接生成的文件
# "rm"是文件删除命令,选项-f含义是忽略不存在的文件,并且不显示删除信息
# (cd mm;make clean)表示进入mm/目录,执行该目录Makefile文件中的clean规则
clean:
 rm -f Image System.map tmp_make core boot/bootsect boot/setup
 rm -f init/*.o tools/system tools/build boot/*.o
 (cd mm;make clean)
 (cd fs;make clean)
 (cd kernel;make clean)
 (cd lib;make clean)

#
# 该规则首先执行上面的clean规则,然后对linux/目录进行压缩,生成backup.Z压缩文件。
# "cd .."表示退到linux/的上一级(父)目录
# "tar cf - linux"表示对linux/目录执行tar归档程序,-cf表示需要创建新的归档文件
# "| compress -"表示将tar程序的执行通过管道操作(‘|‘)传递给压缩程序compress,并将压缩程序的输出存成backup.Z文件
# sysn同步命令迫使缓冲块数据立即写盘并更新超级块
#
backup: clean
 (cd .. ; tar cf - linux | compress - > backup.Z)
 sync

#
# ???zzz
# 该规则用于各文件的依赖关系。创建这些依赖关系是为了给make用来确定是否需要重建一个目标对象
# 比如当某个文件头被改动过后,make就通过生成的依赖关系,重新编译与该头文件有关的所有*.c文件。
# 具体方法如下:
 # 使用字符串编辑程序sed对Makefile文件(这里即是自己)进行处理,
 # 输出为删除Makefile文件中"### Dependencies"行后面的所有行,并生成tmp_make临时文件
 # 然后对init/目录下的每一个C文件(其实只有一个C文件main.c)执行gcc预处理操作
 # -M标志告诉预处理程序输出描述每个目标文件相关性的规则,并且这些规则符合make语法
 # 对于每一个源文件,预处理程序输出一个make规则,其结果形式是相应源程序文件的目标文件名加上其依赖关系--该源文件中包含的所有头文件列表
 # "$$i"实际上是$($i)的意思,"$i"是前面shell变量的值
 # 然后把预处理结果都加到临时文件tmp_make中,然后将该临时文件复制成新的makefile文件
#
dep:
 sed ‘/\#\#\# Dependencies/q‘ < Makefile > tmp_make
 (for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make
 cp tmp_make Makefile
 (cd fs; make dep)
 (cd kernel; make dep)
 (cd mm; make dep)

### Dependencies:
init/main.o : init/main.c include/unistd.h include/sys/stat.h \
  include/sys/types.h include/sys/times.h include/sys/utsname.h \
  include/utime.h include/time.h include/linux/tty.h include/termios.h \
  include/linux/sched.h include/linux/head.h include/linux/fs.h \
  include/linux/mm.h include/signal.h include/asm/system.h include/asm/io.h \
  include/stddef.h include/stdarg.h include/fcntl.h

时间: 2024-11-06 16:11:52

分析Linux 0.11中的kernel部分的makefile文件的相关文章

Linux 0.11 中字符设备的使用

Linux 0.11 字符设备的使用 一.概述 本文自顶向下一步步探索字符设备的读写是怎么完成的.通常我们在Linux应用程序中用open.read.write对各种类型的文件进行操作.我们可以从键盘输入,然后命令行窗口会显示你的输入,有输出的话则命令行窗口会显示输出.为什么所有的设备在Linux中都被看成是一个个文件,可以通过统一的read.write直接进行读写?文件句柄与终端设备有什么关联?为什么Linux允许多个控制终端登录?tty又是什么东西?读写时将发生哪些硬件中断,驱动程序是怎么回

Linux 0.11中write实现

看了一下Linux 0.11版本write的实现,首先它在标准头文件unistd.h中有定义 int write(int fildes, const char * buf, off_t count); 接下来看write.c /* * linux/lib/write.c * * (C) 1991 Linus Torvalds */ #define __LIBRARY__ #include <unistd.h> //定义write的实现 _syscall3(int,write,int,fd,co

[转载]Linux 环境下编译 0.11版本内核 kernel

最近在看<linux内 核0.11完全注释>一书,由于书中涉及汇编语言的地方众多,本人在大学时汇编语言学得一塌糊涂,所以实在看不下去了,头都大了只好匆匆看了个头尾(前面 几章和最后一章).看来即使有<九阴真经>这样的武功秘籍,内功不够也是修炼不出来神马来的.于是索性下了个0.11版本的kernel下来尝试编译一 把. linux-0.11.tar.gz 下载地址: 下面开始工作: 1. tar xvfz linux-0.11.tar.gz 2. cd linux-0.11 3. m

Linux 0.11下信号量的实现和应用

Linux 011下信号量的实现和应用 生产者-消费者问题 实现信号量 信号量的代码实现 关于sem_wait和sem_post sem_wait和sem_post函数的代码实现 信号量的完整代码 实现信号量的系统调用 测试用的应用程序的实现 Linux 0.11下信号量的实现和应用 1.生产者-消费者问题 从一个实际的问题:生产者与消费者出发,谈一谈为什么要有信号量?信号量用来做什么? 问题描述:现在存在一个文件”.\buffer.txt”作为一个共享缓冲区,缓冲区同时最多只能保存10个数.现

基于 Docker 快速构建 Linux 0.11 实验环境

by Falcon of TinyLab.org 2015/05/02 简介 五分钟内搭建 Linux 0.11 的实验环境介绍了如何快速构建一个 Linux 0.11 实验环境. 本文介绍如何快速构建一个独立于宿主机的 Linux 0.11 实验环境,该实验环境可以用于任何操作系统的宿主开发机,将非常方便各类学生学习 Linux 0.11,本文只介绍 Ubuntu.在 Windows 和 Mac 下可以用 VirtualBox + Boot2Docker 来启动. 下文要求已经安装 git 和

mysql 8.0.11 中使用 grant ... identified by 时 error 1064 near &#39;identified by &#39;密码&#39;&#39; at line 1

看一下问题图片: 1 问题: 当使用 grant 权限列表 on 数据库 to '用户名'@'访问主机' identified by '密码'; 时会出现"......near 'identified by '密码'' at line 1"这个错误 2 原因: 因为新版的的mysql版本已经将创建账户和赋予权限的方式分开了 3解决办法: 创建账户:create user '用户名'@'访问主机' identified by '密码'; 赋予权限:grant 权限列表 on 数据库 to

在 DotNetCore 3.0 程序中使用通用协议方式启动文件关联应用

原文:在 DotNetCore 3.0 程序中使用通用协议方式启动文件关联应用 问题描述 在传统的基于 .NET Framework 的 WPF 程序中,我们可以使用如下代码段启动相关的默认应用: # 启动默认文本编辑器打开 helloworld.txt Process.Start("helloworld.txt"); # 启动默认浏览器打开 https://hippiezhou.fun/ Process.Start("https://hippiezhou.fun/"

Linux 0.11 内核学习之main.c

1.之所以选择这么低的版本学习,答案是简单,高版本的代码量太大,对于我这样的初学者来说,就是瞎子摸象不会有什么感觉.开始吧! 2首先你需要在一个地方下载源码:OldLinux 3.分析: 1 /* 2 * linux/init/main.c 3 * 4 * (C) 1991 Linus Torvalds 5 */ 6 7 #define __LIBRARY__ //在unistd.h中,使用了#ifndef __LIBRARY__ 8 #include <unistd.h> //包含units

DICOM医学图像处理:全面分析DICOM3.0标准中的通讯服务模块

背景: 最近在做关于PACS终端与RIS系统之间进行worklist查询的相关调试工作,因此又重新对DICOM3.0标准中关于网络传输的部分进行了阅读,在此将本周的工作进行一下总结,以加深对DICOM3.0标准的认识,从底层更加清晰的了解worklist查询.C-STORE.C-FIND等各种服务. 要点: 1)名词简称 该部分中会出现很多的常见名词的缩写,因此为了更好的理解其含义,先给出各个名词所对应的全称,这里没有用中文进行翻译原因有二,其一是因为英文很简单,而且表意很清楚,其二是因为目前D