从零开始操作系统-02:HelloWorld

这一节主要利用 GRUB 来引导 Kernel 以在屏幕上显示出来 “Hello world”。

所需要的文件在Github:https://github.com/yongkangluo/Ubuntu20.04OS/tree/main/Files/Lec2-HelloWord

1. 什么是multiboot?

每一个操作系统在开机时都是需要一个引导系统的,而不同的操作系统对应的引导程序是不同的。而 multiboot 就是一个对引导系统的规范。“It specifies an interface between a boot loader and a operating system, such that any complying boot loader should be able to load any complying operating system.”
在这里插入图片描述
魔数 是无法更改的。The field ‘magic’ is the magic number identifying the header,
which must be the hexadecimal value 0x1BADB002.

flags 第 0 位表示 4K 对齐,第 1 位表示则必须通过Multiboot信息结构(参见引导信息格式)的mem_*域包括可用内存的信息。如果引导程序能够传递内存分布(mmap_*域)并且它确实存在,则也包括它(内存地图)

checksum是一个32位的无符号值,当与其他的magic域(也就是magic和flags)相加时,结果必须是32位的无符号值0(即magic + flags + checksum = 0)

2. 什么是GRUB?

GURB 手册原文:GRUB 是一个操作系统的引导程序。所以我们生成 kernel 文件以后,需要使用 GRUB 对操作系统实现引导,才能启动生成 iso 文件。
“GNU GRUB is a very powerful boot loader, which can load a wide variety of free operating systems, as well as proprietary operating systems with chain-loading. GRUB is designed to address the complexity of booting a personal computer; both the program and this manual are tightly bound to that computer platform, although porting to other platforms may be addressed in the future.”

安装 GRUB 傻瓜式安装:

sudo apt-get install grub-common
3. 什么是QEMU?

是一个免费的开源仿真器(QuickEMUlator)。它通过动态二进制转换模拟计算机的处理器,并为计算机提供一组不同的硬件和设备模型,使其能够运行各种来宾操作系统。它可以与 Kernel-based Virtual Machine (KVM)互操作,以接近本地速度运行虚拟机。
QEMU is a free and open-source emulator (Quick EMUlator). It emulates the machine’s processor through dynamic binary translation and provides a set of different hardware and device models for the machine, enabling it to run a variety of guest operating systems. It can interoperate with Kernel-based Virtual Machine (KVM) to run virtual machines at near-native speed. QEMU can also do emulation for user-level processes, allowing applications compiled for one architecture to run on another.

sudo apt-get install qemu
4. 构建内核系统

因此在内核中首先需要构建 multiboot 引导文件:

// multiboot.h
#define MB_MAGIC 0x1BADB002

#define MB_ALIGNED_4K_MEM_MAP 0x03
// flag 的 0、1 位置置为1
#define CHECKSUM(flags)    -(MB_MAGIC + flags)

下面的是kernel内核:

#include "multiboot.h"
.section .multiboot
    .long MB_MAGIC
    .long MB_ALIGNED_4K_MEM_MAP
    .long CHECKSUM(MB_ALIGNED_4K_MEM_MAP)

.section .bss
/* 栈:
首先需要栈的位置16对齐的,不然会出现未知的bug;
分配的大小16KB
*/
    .align 16
    stack_bottm:
        .skip 16318, 0
    stack_top:

.section .text
    .global start_
    start_:
    	// 需要设置的地址
        movl $stack_top, %esp

        // 还有需要设置GDT 和IDT 还需要分页
        call _kernel_init

        pushl %ebx
        call _kernel_main

        cli 
    j_:
        hlt
        jmp j_

解释:
.bss:
In computer programming, the block starting symbol (abbreviated to .bss or bss) is the portion of an object file, executable, or assembly language code that contains statically allocated variables that are declared but have not been assigned a value yet. It is often referred to as the “bss section” or “bss segment”.

.align: 第一个参数是对其的边界,第二个参数是使用什么填充,省略为0
.align abs-expr, abs-expr, abs-expr
Pad the location counter (in the current subsection) to a particular storage boundary. The first expression (which must be absolute) is the alignment required, as described below.
The second expression (also absolute) gives the fill value to be stored in the padding bytes. It (and the comma) may be omitted. If it is omitted, the padding bytes are normally zero. However, on some systems, if the section is marked as containing code and the fill value is omitted, the space is filled with no-op instructions.
The third expression is also absolute, and is also optional. If it is present, it is the maximum number of bytes that should be skipped by this alignment directive. If doing the alignment would require skipping more bytes than the specified maximum, then the alignment is not done at all. You can omit the fill value (the second argument) entirely by simply using two commas after the required alignment; this can be useful if you want the alignment to be filled with no-op instructions when appropriate.

5. 显示设置

内核中调用了 _kernel_main:

void _kernel_main(void* info_table){
    //Todo
    tty_set_theme(VGA_COLOR_GREEN, VGA_COLOR_BLUE);
    tty_put_str("hello kernel world!\nThis is second.");
}

这里做的就是打印效果。其他的文件都在github里面,就不详细介绍了。

6. Linker
7. Makefile

构建好所有代码之后,我们需要编译链接,但是使用逐步的命令太繁琐,所有设置makefile文件对代码实现统一的链接。具体代码在github中。

ENTRY(start_)

SECTIONS {
    . = 0x100000;
    /* boot loader 自动将内核加载到 1 MB
    的位置 */
    .text BLOCK(4K) : {
        * (.multiboot)
        * (.text)
    }
    .bss BLOCK(4K) : {
        * (COMMON)
        * (.bss)
    }
    .data BLOCK(4K) : {
        * (.data)
    }
    .rodata BLOCK(4K) :{
        * (.rodata)
    }

}
8. make all && make run

进入目录使用make all 进行编译链接,make run 进行运行。

方法主要跟着B站Up主做的,B站视频链接在:https://www.bilibili.com/video/BV1jL4y1s7X6/?spm_id_from=333.788&vd_source=72ce864f895f9fbf22b81450817f2875

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值