[转载]Linux 环境下编译 0.11版本内核 kernel
最近在看《、如果Clobber/Modify 为空,则其前面的冒号(:)必须省略。
2、如果Output,Input,Clobber/Modify都为空,Output,Input之前的冒号(:)既可以省略,也可以不省略。
3、如果Input,Clobber/Modify为空,但Output不为空,Input前的冒号(:)既可以省略,也可以不省略。
4、如果后面的部分不为空,而前面的部分为空,则前面的冒号(:)都必须保留,否则无法说明不为空的部分究竟是第几部分。
每一个Input和Output表达式都必须指定自己的操作约束Operation Constraint,这里将讨论在80386平台上所可能使用的操作约束。
当前的输入或输出需要借助一个寄存器时,需要为其指定一个寄存器约束,可以直接指定一个寄存器的名字。
常用的寄存器约束的缩写
约束 意义
r 表示使用一个通用寄存器,由 GCC 在%eax/%ax/%al,%ebx/%bx/%bl,%ecx/%cx/%cl,%edx/%dx/%dl中选取一个GCC认为合适的。
g 表示使用任意一个寄存器,由GCC在所有的可以使用的寄存器中选取一个GCC认为合适的。
q 表示使用一个通用寄存器,和约束r的意义相同。
a 表示使用%eax/%ax/%al
b 表示使用%ebx/%bx/%bl
c 表示使用%ecx/%cx/%cl
d 表示使用%edx/%dx/%dl
D 表示使用%edi/%di
S 表示使用%esi/%si
f 表示使用浮点寄存器
t 表示使用第一个浮点寄存器
u 表示使用第二个浮点寄存器
如果一个Input/Output 操作表达式的C/、make
In file included from stat.c:13:
../include/asm/segment.h: Assembler messages:
../include/asm/segment.h:27: Error: bad register name '%sil'
make[1]: *** [stat.o] Error 1
make[1]: Leaving directory '***/linux-0.11/fs'
make: *** [fs/fs.o] Error 2
出错原因:
fs 目录下的 Makefile 中编译选项使用了 -O 优化选项导致寄存器错误
解决方法:
将fs目录下的Makefile 文件中的
CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer \
修改为
CFLAGS =-Wall -fstrength-reduce -fomit-frame-pointer \
14、make
tools/build.c: In function 'main':
tools/build.c:75: warning: implicit declaration of function 'MAJOR'
tools/build.c:76: warning: implicit declaration of function 'MINOR'
tmp/ccsMKTAS.o: In function 'main':
build.c:(.text+0xe1): undefined reference to 'MAJOR'
build.c:(.text+0xf7): undefined reference to 'MINOR'
collect2: ld returned 1 exit status
出错原因:'MAJOR' 和 'MINOR' 未定义
解决办法:
我们可以在 include/linux/fs.h 文件中找到
#define MAJOR(a) (((unsigned)(a))>>8)
#define MINOR(a) ((a)&0xff)
而在 tools/build.c 中也有包含 #include <linux/fs.h>
那么再看第一层目录中的主 Makefile 文件
tools/build: tools/build.c
$(CC) $(CFLAGS) \
-o tools/build tools/build.c
好象确实没有引用头文件
简单的添加 -Iinclude
重新编译后出现一堆报标准C库头文件的错误
再添加 -nostdinc
又报 stderr fprintf 之类的错误
没折,只好将
#define MAJOR(a) (((unsigned)(a))>>8)
#define MINOR(a) ((a)&0xff)
添加到 tools/build.c 文件中,然后删除 #include <linux/fs.h>
15、make
make[1]: Leaving directory '***/linux-0.11/lib'
ld -s -x -M boot/head.o init/main.o \
kernel/kernel.o mm/mm.o fs/fs.o \
kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \
kernel/math/math.a \
lib/lib.a \
-o tools/system > System.map
ld: warning: cannot find entry symbol _start; defaulting to 08048a0
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer \
-o tools/build tools/build.c
tools/build boot/bootsect boot/setup tools/system /dev/hd6 > Image
/dev/hd6: No such file or directory
Couldn't stat root device.
make: *** [Image] Error 1
解决办法:
将第一层主 Makefile 文件中的
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
修改为
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
nm tools/system | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)'| sort > System.map
nm命令将目标文件中的各种符号列出来。
ROOT_DEV=/dev/hd6 修改为 ROOT_DEV=
16、make
/DISCARD/
*(.note.GNU-stack)
*(.gnu_debuglink)
*(.gnu.lto_*)
OUTPUT(tools/system elf32-i386)
nm tools/system | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)'| sort > System.map
nm: tools/system: no symbols
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer \
-o tools/build tools/build.c
tools/build boot/bootsect boot/setup tools/system > Image
Root device is (3, 6)
Boot sector 512 bytes.
Setup is 312 bytes.
Non-Gcc header of 'system'
make: *** [Image] Error 1
解决办法:
将第一层主 Makefile 文件中的
LDFLAGS =-s -x -M
修改为
LDFLAGS =-m elf_i386 -Ttext 0 -e startup_32
Image: boot/bootsect boot/setup tools/system tools/build
tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image
sync
修改为
Image: boot/bootsect boot/setup tools/system tools/build
objcopy -O binary -R .note -R .comment tools/system tools/kernel
tools/build boot/bootsect boot/setup tools/kernel $(ROOT_DEV) > Image
rm tools/kernel -f
sync
objcopy命令能复制和转化目标文件
objcopy -O binary -R .note -R .comment tools/system tools/kernel
-O binary tools/system tools/kernel将 tools/system 生成二进制文件 tools/kernel
-R .note -R .comment 删除 .note段 和 .comment 段
将 tools/build.c 文件中的
if (((long *) buf)[5] != 0)
die("Non-GCC header of 'system'");
这段代码注释掉
//if (((long *) buf)[5] != 0)
// die("Non-GCC header of 'system'");
17、make
ld -m elf_i386 -Ttext 0 -e startup_32 boot/head.o init/main.o \
kernel/kernel.o mm/mm.o fs/fs.o \
kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \
kernel/math/math.a \
lib/lib.a \
-o tools/system
nm tools/system | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)'| sort > System.map
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer \
-o tools/build tools/build.c
objcopy -O binary -R .note -R .comment tools/system tools/kernel
tools/build boot/bootsect boot/setup tools/system > Image
Root device is (3, 6)
Boot sector 512 bytes.
Setup is 312 bytes.
System is 128323 bytes.
rm tools/kernel -f
sync
终于编译 linux 内核 0.11 版本成功了!
最 后也可以利用赵炯博士在http://www.oldlinux.org/Linux.old/kernel/0.1x/ 这里提供了修改 linux-0.11-060618-gcc4.tar.gz 好的 0.11版本的内核进行编译,只要修改以下 Makefile 里 -mcpu=i386 为 -march=i386 还需要将 kernel/blk_drv/blk.h 文件第87行 将 #elif 修改为 #else 就可以编译通过了。
总结:编译需要一个过程,学习也是同样需要一个过程。虽然可以利用赵博士修改好的 kernel-0.11 版快速的编译内核,但是那样就不会遇到太多有价值的编译问题,而解决这些问题就是一个学习过程,相信赵博士在编译0.11版本内核的时候也遇到了这些问 题。这样我想起了高中解数学难题的时候,高手解体时总是省略了一些因式分解的过程,而对于菜鸟来说这些省略的过程是非常重要的。
[转载]Linux 环境下编译 0.11版本内核 kernel的更多相关文章
- <摘录>Linux 环境下编译 0.11版本内核 kernel
系统环境:Fedora 13 + gcc-4.4.5 最近在看<linux内核0.11完全注释>一书,由于书中涉及汇编语言的地方众多,本人在大学时汇编语言学得一塌糊涂,所以实在看不下去了, ...
- Suse环境下编译linux-2.6.24内核
Suse环境下编译linux-2.6.24内核 1.下载linux-2.6.24内核源码: https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/ ...
- 在虚拟机linux环境下编译windows版adb fastboot
原文出自:http://blog.chinaunix.net/uid-20546441-id-1746200.html 我根据虚拟机编译遇到的问题进行一些添加 [前提条件] Linux Android ...
- Linux环境下编译并执行ava helloworld程序
原文:http://blog.lupaworld.com/home-space-uid-24466-do-blog-id-2578.html 已经学会怎样在Windows下怎样编辑,编译和运行Java ...
- linux环境下编译C++ 程序
GCC(GNU Compiler Collection)是Linux下最主要的编译工具,GCC不仅功能非常强大,结构也异常灵活.它可以通过不同的前端模块来支持各种语言,如:Java.Fortran.P ...
- Linux环境下编译JDK
环境准备 操作系统,ubuntu-14.04.6-desktop-amd64.iso,下载地址:http://59.80.44.100/releases.ubuntu.com/14.04/ubuntu ...
- 分布式缓存技术memcached学习(一)——linux环境下编译memcahed
安装依赖工具 [root@localhost upload]# yum install gcc make cmake autoconf libtool 下载并上传文件 memcached 依 ...
- 在linux环境下编译运行OpenCV程序的两种方法
原来以为在Ubuntu下安装好了OpenCV之后,自己写个简单的程序应该很容易吧,但是呢,就是为了编译一个简单的显示图片的程序我都快被弄崩溃了. 在谷歌和上StackOverFlow查看相关问题解答之 ...
- 在linux环境下编译android so库
(1) 配置Android NDK环境 (2) mk文件编写 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # OpenCV OPENCV_CA ...
随机推荐
- 常用Git命令大全
Git命令 查看.添加.提交.删除.找回,重置修改文件 git help <command> # 显示command的help git show # 显示某次提交的内容 git show ...
- Oracle SQL自带函数整理
数字函数 abs(n):用于返回数字n的绝对值 ceil(n):返回大于等于数字n的最小整数 floor(n):返回小于等于数字n的最大整数 mod(m,n):返回m/n数字相除后的余数,如果n=0, ...
- 【Python之路】第九篇--Python基础之线程、进程和协程
进程与线程之间的关系 线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除.线程可与属于同一进程的其它线程共享进程所拥有的全 ...
- Spring的字符编码过滤器CharacterEncodingFilter
Spring中的字符编码过滤器,用来解决我们项目中遇到的编码问题. 使用方式特别友好,在web.xml加入: <filter> <description>字符集过滤器</ ...
- B/S和C/S的区别。
现在软件开发的整体架构主要分为B/S架构与C/S架构 一,C/S——Client/Service:客户机/服务器模式: C/S (Client/Server)结构,即大家熟知的客户机和服务器结构.它是 ...
- 《Javascript网页经典特性300例》
<Javascript网页经典特性300例> 基础篇 第1章:网页特性 刷新.后退.前进.关闭.标题.跳转禁止网页放入框架动态加载js避免浏览器使用缓存加载页面 第2章:DOM操作 根据n ...
- POJ 2773 Happy 2006#素数筛选+容斥原理+二分
http://poj.org/problem?id=2773 说实话这道题..一点都不Happy好吗 似乎还可以用欧拉函数来解这道题,但正好刚学了容斥原理和二分,就用这个解法吧. 题解:要求输出[1, ...
- POJ 1845 Sumdiv#质因数分解+二分
题目链接:http://poj.org/problem?id=1845 关于质因数分解,模板见:http://www.cnblogs.com/atmacmer/p/5285810.html 二分法思想 ...
- POJ 1789 Truck History(Prim+邻接矩阵)
( ̄▽ ̄)" #include<iostream> #include<cstdio> #include<cstring> #include<algo ...
- Java 集合 集合与数组之间的转换
Java 集合 集合与数组之间的转换 @author ixenos 数组转集合 Arrays.asList(T... a) 先给结论:用 Arrays.asList(T... a) 将数组转换成集合 ...