Micernel构建日记——第一天

概述

Micernel的设计目的是为了了解操作系统技术,深入的去理解当今计算机领域发展所取得的各种技术突破与成就。同时以现代操作系统技术为基础,去探索在操作系统与AI更紧密结合相互发展的方式方法。
现代操作系统发展至今已经有了更多不同的思路与技术突破,同时很多人也没有一个很好的方法去深刻的理解其中的各种技术。本着知其然必知其所以然的原则,去重走一遍操作系统构建之路,在这其中希望能获得更多新的思路,萌生出别样的火花。
对于操作系统的研究不能不提现在很流行的开源操作系统linux,但随着linux的发展,其代码也是越来越多,学习难度也是越来越大,各个子模块或子系统之间的关系也是变得越来越复杂。所以这个项目也是想实现一个更易于理解,模块之间接口更清晰,同时能够囊括操作系统技术中大部分关键技术细节的操作系统。并且构思一种系统能够自行进化的解决途径,使系统能够随着时间,信息的增加而变得越来越智能,或者说是一种自学习的方案。
本文适合对操作系统有兴趣,对于C,汇编,计算机体系结构等相关知识有一定基础的同学阅读,因为主要是做项目跟踪与思路分享之用,许多基础性的东西都不会在这儿深入展开,而会把重心放在蓝图设计与编码实现上,也很欢迎有志学习的人能够加入到项目中来。

第一天设计目标

x86平台是现在个人电脑用户都能接触到的平台,各种虚拟机都能够做到对x86平台的模拟,所以我们从x86平台开始。第一天的任务很简单,了解x86平台,了解grub,了解引导协议,在前面都完成的基础上,我们需要能够使用grub2实现引导。
x86平台介绍,指令集介绍及系统开发手册:
https://software.intel.com/en-us/articles/intel-sdm
intel处理器及AMD处理器演变历史:
http://wiki.osdev.org/IA32_Architecture_Family
grub历史演变及特点:
https://en.wikipedia.org/wiki/GNU_GRUB
grub源码:
http://www.gnu.org/software/grub/grub-download.html
linux x86引导协议:
https://www.kernel.org/doc/Documentation/x86/boot.txt
《自己动手写操作系统》——于渊
《x86汇编语言:从实模式到保护模式》——李忠 王晓波
AT&T汇编入门简介:
http://blog.csdn.net/ztguang/article/details/51011771
AT&T汇编与Intel汇编区别:
http://blog.csdn.net/lnuyasha_hrb/article/details/6469621
汇编语言——王爽
汇编语言程序设计——Richard Blum

好了,以上介绍了在开始之前需要知道了解的一些东西,在之后对于一些不必要的细节将省略,重点放在设计思路上,这样可以帮助我们抓住主要的东西而不会迷失在细节的海洋里,更重要的是在之后在这更想将这儿用来记录思考的过程与一些无聊(^_^)。。的想法分享的地方和对项目进展进行与问题记录的地方。

过程记录

结合linux的源码和引导协议的文档制作grup引导所需要的setup,制作setup有一下几点需要注意的:
1.与linux内核镜像生成过程类似,需要将setup与内核合成一个文件,这是必须的,除非自己实现引导程序
2.setup的大小有限制,这取决与引导加载程序,grub中限制了setup最大不能超过64*512=32kb,如果在setup中没根据协议设置自身大小,grub默认setup大小为2kb
3.将setup与内核合成一个文件涉及对setup中引导协议关键字段的填充,需要一个工具完成这件事儿

设计思路:
|0|0x7c00|...|0x1000000
| |setup |...|micernel
目前grub2将setup(包含实模式代码和引导协议)放置在0x7c00起始的位置,内核代码加载到0x1000000开始的位置,这些都是历史原因造成的,为了保证我们能够使用grub2引导我们需要做到像linux那样的内核构建方式。

制作setup
这部分我们只需要包含引导协议即可,仿造linux的head.S代码构建
/*setup.S*/
    .code16
    .section ".bstext", "ax"
    .global bootsect_start
bootsect_start:
# Normalize the start address
    ljmp    $0x7c0, $start2
start2:
    movw    %cs, %ax
    movw    %ax, %ds
    movw    %ax, %es
    movw    %ax, %ss
    xorw    %sp, %sp
    sti
    cld
    movw    $bugger_off_msg, %si

msg_loop:
    lodsb
    andb    %al, %al
    jz  bs_die
    movb    $0xe, %ah
    movw    $7, %bx
    int $0x10
    jmp msg_loop
bs_die:
    # Allow the user to press a key, then reboot
    xorw    %ax, %ax
    int $0x16
    int $0x19
    # int 0x19 should never return.  In case it does anyway,
    # invoke the BIOS reset code...
    ljmp    $0xf000,$0xfff0
    .section ".bsdata", "a"
bugger_off_msg:
    .ascii  "Use a boot loader.\r\n"
    .ascii  "\n"
    .asciz  "Remove disk and press any key to reboot...\r\n"
kernel_version:
    .asciz  "20170224"

    .section ".header" , "a"
    .global sentinel
sentinel:           .byte 0xff,0xff
    .global hdr
hdr:
    setup_sects:    .byte 0
    root_flags:     .word 1
    syssize:        .long 0
    ram_size:       .word 0
    vid_mode:       .word 0xfffd /* ask for it at bootup */
    root_dev:       .word 0
    boot_flag:      .word 0xaa55

    .global _start
_start:
    .byte 0xeb
    .byte   start_of_setup-1f

    # Part 2 of the header, from the old setup.S

    .ascii  "HdrS"      # header signature
    .word   0x020d      # header version number (>= 0x0105)
                    # or else old loadlin-1.5 will fail)
        .globl realmode_swtch
realmode_swtch: .word   0, 0        # default_switch, SETUPSEG
start_sys_seg:  .word   0x1000      # obsolete and meaningless, but just
                    # in case something decided to "use" it
    .word   kernel_version # pointing to kernel version string
                    # above section of header is compatible
                    # with loadlin-1.5 (header v1.5). Don't
                    # change it.

type_of_loader: .byte   0       # 0 means ancient bootloader, newer
                    # bootloaders know to change this.
                    # See Documentation/x86/boot.txt for
                    # assigned ids

# flags, unused bits must be zero (RFU) bit within loadflags
loadflags:
    .byte   LOADED_HIGH # The kernel is to be loaded high

setup_move_size: .word  0x8000      # size to move, when setup is not
                    # loaded at 0x90000. We will move setup
                    # to 0x90000 then just before jumping
                    # into the kernel. However, only the
                    # loader knows how much data behind
                    # us also needs to be loaded.

code32_start:               # here loaders can put a different
                    # start address for 32-bit code.
    .long   0x100000    # 0x100000 = default for big kernel

ramdisk_image:  .long   0       # address of loaded ramdisk image
                    # Here the loader puts the 32-bit
                    # address where it loaded the image.
                    # This only will be read by the kernel.

ramdisk_size:   .long   0       # its size in bytes

bootsect_kludge:
    .long   0       # obsolete

heap_end_ptr:   .word   _end+512-512
                    # (Header version 0x0201 or later)
                    # space from here (exclusive) down to
                    # end of setup code can be used by setup
                    # for local heap purposes.

ext_loader_ver:
    .byte   0       # Extended boot loader version
ext_loader_type:
    .byte   0       # Extended boot loader type

cmd_line_ptr:   .long   0       # (Header version 0x0202 or later)
                    # If nonzero, a 32-bit pointer
                    # to the kernel command line.
                    # The command line should be
                    # located between the start of
                    # setup and the end of low
                    # memory (0xa0000), or it may
                    # get overwritten before it
                    # gets read.  If this field is
                    # used, there is no longer
                    # anything magical about the
                    # 0x90000 segment; the setup
                    # can be located anywhere in
                    # low memory 0x10000 or higher.

initrd_addr_max: .long 0x7fffffff
                    # (Header version 0x0203 or later)
                    # The highest safe address for
                    # the contents of an initrd
                    # The current kernel allows up to 4 GB,
                    # but leave it at 2 GB to avoid
                    # possible bootloader bugs.

kernel_alignment:  .long 0x1000000  #physical addr alignment
                        #required for protected mode
                        #kernel
relocatable_kernel:    .byte 1
min_alignment:      .byte 21
#define X86_64 (1<<0)
#define CAN_BE_LOADED_ABOVE_4G (1<<1)
#define EFI_STUB 0
#define EFI_KEXEC 0
xloadflags:
    .word X86_64 | CAN_BE_LOADED_ABOVE_4G | EFI_STUB | EFI_KEXEC
cmdline_size:   .long   2048-1     #length of the command line,
                                                #added with boot protocol
                                                #version 2.06
hardware_subarch:   .long 0         # subarchitecture, added with 2.07
                        # default to 0 for normal x86 PC
hardware_subarch_data:  .quad 0
payload_offset:     .long ZO_input_data
payload_length:     .long ZO_z_input_len
setup_data:     .quad 0         # 64-bit physical pointer to
                        # single linked list of
                        # struct setup_data
pref_address:       .quad 0x1000000 # preferred load addr
init_size:      .long 0     # kernel initialization size
handover_offset:    .long 0         # Filled in by build.c
# End of setup header #####################################################
start_of_setup:
1:
    hlt
    jmp 1b
就像上面代码一样,启动协议这块完全按照linux来,因为目前不会用到efi,所以暂时舍弃efi的配置部分。这一块是比较死的东西,没有什么可以扩展或创新的地方,遵从协议保持兼容性是最好的做法。
剩下的是编译和生成部分,这块都是一些比较常规的做法,如果有兴趣可具体参考源代码。

项目地址和Commit说明

每次提交会尽量做到与博客记录的进度同步,可能会出现的情形是篇文章的内容对应几次提交,这中情况出现时会做特别说明,提交的描述和代码注释会尽可能的详细易懂。
项目地址:

因项目暂未上传git服务器,上传后更新地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值