x01.os: 换心术

来源:互联网 发布:最好的健身软件 编辑:程序博客网 时间:2024/04/28 03:15

编译内核

在 linux 中编译 linux, 于是 linux 便有了再生能力。这不同于自然界的缓慢进化,可用神速来形容。—— 和强大的 windows 相抗衡,便是证明!

我在 ubuntu 中的编译方法如下:

1.在 www.kernel.org 中下载 linux-3.18 内核源代码并解压到 /home/linux,由终端进入该目录,输入命令:make help ,可先看看所提供的操作。

2.输入: sudo make i386-defconfig ,可获取默认配置。

3.输入: sudo make ,可生成所需内核。

4.输入:sudo make install ,可完成内核安装及配置。

现在是看成果的时候了。重启电脑,在启动菜单中选择第二项:高级选项,可清楚看到,刚编译的 linux-3.18 还冒着热气呢。由此进入,发现上不了网,可能是默认配置惹的祸吧。但这并不重要,因为目的已达到:换了一颗崭新的心。

现在来进行一下清理。

1.重启选择先前的版本进入系统,由终端进入 /home/linux 目录,输入: sudo make distclean,可清理生成的所有文件及配置。

2.由终端进入 /boot 目录,输入:sudo rm -f *linux-3.18.0,可删除刚安装的内核。当然,删除前,用 ls 命令确认一下是必要的。

3.输入:sudo update-grub,更新一下启动菜单。

OK!

又:前段时间,为国产操作系统吵死了。其实,在互联网时代,资源如此丰富,自己 DIY 一个系统也不是难事,又有什么可吵的呢?

MBR 初探

硬盘不同于软盘,它是要分区的。这时,mbr(master boot record)便不可少了。安装 os 硬盘的第一扇区,开始有一小段不多于 446 字节的程序,然后是分区表 512-446-2 字节,然后是引导标志 0xAA55 两字节。这一小段程序,便是 mbr 的主体。mbr 首先将其自身复制到 0x0600 处,代码如下:

复制代码
; 0x7C00 => 0x0600    mov        si, sp    push       si    mov        di, 0x0600    mov        cx, 0x200    cld    rep        movsw    
复制代码

这是要给分区的引导代码腾位置。操作系统的引导代码,可能位于软盘,光盘等 Media 中,其代码首先便是 org   0x7C00,所以 mbr 复制自身进行重定位,就必不可少了。

第二步,当然就是寻找活动分区的启动代码了。有这么一句:test  dl, dl。这个 dl 的值,便是 drive number, 由 bios 的 int 0x19 取得。通过 dl 判断设备的类型,作不同的选择。mbr.s 的内容如下:

; ----------------------; mbr.s (c) 2014 by x01; ----------------------P_EntrySize        equ        16        ; 分区表每项为 16 字节P_PartOffset    equ        0x1BE     ; 分区表在引导扇区的偏移位置P_BootOffset    equ        0        ; 分区项中引导标志的偏移位置P_TypeOffset    equ        4        ; 分区项中分区类型的偏移位置P_LbaOffset        equ        8        ; 分区项中起始扇区 LBA 的偏移位置; Partition table struct; ----------------------; offset    len                    description;   0         1            状态(80h=可引导,00h=不可引导,其他不合法);    1         1            起始磁头号;    2         1            起始扇区号(仅用了低 6 位,高 2 位为起始柱面号的第 8-9 位;    3         1            起始柱面号的低 8 位;    4         1            分区类型(System ID);    5         1            结束磁头号;    6         1            结束扇区号(仅用了低 6 位,高 2 位为结束柱面号的第 8-9 位;    7         1            结束柱面号的低 8 位;    8         4            起始扇区的 LBA;    12         4            扇区数目boot:    xor        ax, ax    mov        ds, ax    mov        es, ax    cli    mov        ss, ax        ; ds = es = ss = 0, 段偏移地址直接映射为物理地址    mov        sp, 0x7C00    sti    ; 0x7C00 => 0x0600    mov        si, sp    push    si    mov        di, 0x0600    mov        cx, 0x200    cld    rep        movsw    jmp        0:0x0600 + activeactive:    test    dl, dl        ; BIOS int 19h => dl = drive_nr                        ; SF <- MSB(dl): most significact bit, 1 is -, 0 is +    jns        nextdisk    mov        si, 0x0600 + P_PartOffset    find:    cmp        byte [si + P_TypeOffset], 0        ; if not equal 0 then can use    jz        nextpart    test    byte [si + P_BootOffset], 0x80    ; 0x80: bootable    jz        nextpartloadpart:    call    load    jc        error    ret                ; goto secondary boot => 0x0000:0x7C00    nextpart:    add        si, P_EntrySize    cmp        si, 0x0600 + P_PartOffset + 4 * P_EntrySize    jb        find        call    print    db        "No active partition\0"    jmp        reboot    nextdisk:    inc        dl    test    dl, dl    js        nexthd    int        0x11        ; get active drive info    shl        ax, 2        ; floppy info at al[6-7], but after shl at ah[0-1]    and     ah, 3    cmp        dl, ah        ; dl <= ah then floppy exist    ja        nextdisk    call    loadfloppy    jc        nextdisk    ret    nexthd:    call    loadfloppyerror:    jc        handle_err    ret; load floppy 0 sectorloadfloppy:    mov        si, 0x0600 + zero - P_LbaOffset    ; load hd bootload:    mov        di, 3    retry:    push    dx    ; dl = old drive_nr protect        push    es    push    di        ; Get disk info(int 0x13: ah=0x8)    ; ch: cyl low 8 bit, cl[6-7]: cyl high 2 bit    ; cl[0-5]: sectors per track    ; dh: heads, dl: drive_nr    mov        ah, 0x08    int        0x13        pop        di    pop        es        and        cl, 0x3F    ; sectors base 1    inc        dh            ; heads base 0, so inc        mov        al, cl        ; al = cl = sectors per track    mul        dh            ; ax = cyl sectors = heads * sectors_per_track    mov        bx, ax        mov        ax, word [si + P_LbaOffset + 0]    mov        dx, word [si + P_LbaOffset + 2]    ; dx:ax = secondary boot offset        cmp        dx, (0x16390 * 0xFF * 0x3F - 0xFF) >> 0x10    jae        bigdisk        div        bx        ; /: ax is cyl_nr, mod: dx is cyl_offset    xchg    ax, dx    mov        ch, dl    ; ch is cyl_nr low 8 bit        div        cl        ; /: al is head_nr, mod: ah is track offset(base 0)    xor        dl, dl    shr        dx, 2    ; dl[6-7] = cyl_nr high 2 bit    or        dl, ah    ; dl low 5 bit store track offset    mov        cl, dl    ; cl high 2 bit is cyl high 2 bit, cl low 5 bit is track offset    inc        cl        ; base 1    pop        dx        ; old drive_nr    mov        dh, al    ; head_nr => dh    mov        bx, 0x7C00    ; es:bx is load addr    mov        ax, 0x0201    ; read disk sector entry_point parameter    int        0x13        ; read 1 sector to es:bx    jmp        read_check    bigdisk:    mov        bx, dx    pop        dx    push    si    mov        si, 0x0600 + dap_offset    ; dap: disk addr packet, for up 8G    mov        word [si + 8], ax        ; low     mov        word [si + 0xA], bx        ; high    mov        ah, 0x42                ; extend read parameter    int        0x13    pop        si    read_check:    jnc        read_ok    cmp        ah, 0x80    ; timeout    je        read_bad    dec        di    jl        read_bad    xor        ah, ah    int        0x13    jnc        retry    read_bad:    stc    ret        ; have a bug, need clear zero    read_ok:    cmp        dword [0x7C00 + 510], 0xAA55    jne        notboot    ret    notboot:    call    print    db        "Not bootable\0"    jmp        reboot    handle_err:    mov        si, 0x7C00 + err_nr + 1        ; err_nr low bit    print_num:    mov        al, ah    ; ah: int 0x13 error code    and        al, 0x0F    cmp        al, 0xA    jb        digit    add        al, 0x7    digit:    add        byte [si], al    ; err_nr low bit is '0', after add is correct number    dec        si                ; err_nr high bit    mov        cl, 4    shr        ah, cl    jnz        print_num    call    print    db        "Read error"    err_nr:    db        "00\0"    reboot:    call     print    db        "Hit any key reboot.\0"    xor        ah, ah    int        0x16    ; wait key    call    print    db        "\r\n\0"    int        0x19    ; reboot    print:    pop        si        ; ip => get string addrprint_next:    lodsb            ; al = *si++    test    al, al    jz        print_done    mov        ah, 0x0E    mov        bx, 0x0001    int        0x10    jmp        print_next    print_done:    jmp        si    dap_offset:    PacketSize        db    0x10    Reserved        db    0x0    BlockCount        dw    0x1    BufferOffset    dw    0x7C00    BufferSegment    dw    0x0    BlockNumLow        dd    0x0zero:    BlockNumHigh    dd    0x0    times 510-($-$$)     db    0BootFlag            dw    0xAA55

后面加了两句引导标志,是为了快速检验一下运行效果,实际是不需要的。minix 通过 installboot 程序来完成组装与添加。检验方法如下:

1.编译: nasm -o mbr mbr.s

2.写入硬盘:dd if=mbr of=c.img bs=512 count=1 conv=notrunc

其中,c.img 是硬盘映像。配置 bochs 后运行,可看到因找不到活动分区而停止。当然,这又是另一个问题,就不多说了。



0 0
原创粉丝点击