IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【内核之旅-2】内核编译 -> 正文阅读

[系统运维]【内核之旅-2】内核编译

概述

这次介绍内核的编译脚本

参考资料:
x86架构操作系统内核实现

Makefile文件解析

#!Makefile

C_SOURCES = $(shell find . -name "*.c")
C_OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES))
S_SOURCES = $(shell find . -name "*.s")
S_OBJECTS = $(patsubst %.s, %.o, $(S_SOURCES))

CC = gcc
LD = ld
ASM = nasm

C_FLAGS = -c -Wall -m32 -ggdb -gstabs+ -nostdinc -fno-pic -fno-builtin -fno-stack-protector -I include
LD_FLAGS = -T scripts/kernel.ld -m elf_i386 -nostdlib
ASM_FLAGS = -f elf -g -F stabs

all: $(S_OBJECTS) $(C_OBJECTS) link update_image

.c.o:
    @echo 编译代码文件 $< ...
    $(CC) $(C_FLAGS) $< -o $@

.s.o:
    @echo 编译汇编文件 $< ...
    $(ASM) $(ASM_FLAGS) $<

link:
    @echo 链接内核文件...
    $(LD) $(LD_FLAGS) $(S_OBJECTS) $(C_OBJECTS) -o hx_kernel

.PHONY:clean
clean:
    $(RM) $(S_OBJECTS) $(C_OBJECTS) hx_kernel

.PHONY:update_image
update_image:
    sudo mount floppy.img /mnt/kernel
    sudo cp hx_kernel /mnt/kernel/hx_kernel
    sleep 1
    sudo umount /mnt/kernel

.PHONY:mount_image
mount_image:
    sudo mount floppy.img /mnt/kernel

.PHONY:umount_image
umount_image:
    sudo umount /mnt/kernel

.PHONY:qemu
qemu:
    qemu -fda floppy.img -boot a

.PHONY:bochs
bochs:
    bochs -f tools/bochsrc.txt

.PHONY:debug
debug:
    qemu -S -s -fda floppy.img -boot a &
    sleep 1
    cgdb -x tools/gdbinit

命令的参数解释

gcc —— 编译选项

  • -m32 生成32位机器的汇编代码;
  • -ggdb -gstabs+ 调试信息
  • -nostdinc 不搜索默认路径头文件
  • -fno-builtin 不使用内建函数

ld —— 链接器参数:

  • -T <scriptfile>, --script=<scriptfile> 使用 scriptfile 作为链接器脚本。此脚本将替换 ld 的默认链接器脚本(而不是添加到其中),因此脚本必须指定输出文件所需的所有内容。如果当前目录中不存在脚本文件,ld 会在 -L选项指定的目录中查找

  • -m <emulation> 模拟指定的链接器
    对于我的环境:Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu elf_l1om elf_k1om i386pep i386pe

  • -nostdlib: 不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。这个选项常用于编译内核、bootloader等程序,它们不需要启动文件、标准库文件。
    C语言程序执行的第一条指令。并不是main函数。生成一个C程序的可执行文件时编译器通常会在我们的代码上加上几个被称为启动文件的代crt1.o,crti.o,crtend.o,crtn.o等,他们是标准库文件。这些代码设置C程序的堆栈等,然后调用main函数。他们依赖于操作系统,在裸板上无法执行

nasm —— 选项

ld脚本解析

/*
 *      kernel.ld -- 针对 kernel 格式所写的链接脚本
 */

ENTRY(start)
SECTIONS
{
    /* 段起始位置 */

    . = 0x100000;
    .text :
    {
        *(.text)
        . = ALIGN(4096);
    }

    .data :
    {
        *(.data)
        *(.rodata)
        . = ALIGN(4096);
    }

    .bss :
    {
        *(.bss)
        . = ALIGN(4096);
    }

    .stab :
    {
        *(.stab)
        . = ALIGN(4096);
    }
    
    .stabstr :
    {
        *(.stabstr)
        . = ALIGN(4096);
    }

    /DISCARD/ : { *(.comment) *(.eh_frame) }
}

特殊符号.称为location counter,可以理解为当前的虚拟地址(VMA)
第一条赋值语句. = 0x10000指示ld将当前地址设置为0x10000
第二条描述语句指示ld将所有输入文件的.text段输出到输出文件的.text段,*匹配所有输入文件

参考

Linux 命令(65)—— ld 命令
编译时“-nostdlib”的使用
ld脚本设置

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-01-25 10:59:37  更:2022-01-25 11:01:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 8:51:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码