ucoreOS_lab1实验报告

操作系统镜像文件ucore.img是如何一步一步生成的?

# 构建bin/kernel
+ cc kern/init/init.c
+ cc kern/libs/readline.c
+ cc kern/libs/stdio.c
+ cc kern/debug/kdebug.c
+ cc kern/debug/kmonitor.c
+ cc kern/debug/panic.c
+ cc kern/driver/clock.c
+ cc kern/driver/console.c
+ cc kern/driver/intr.c
+ cc kern/driver/picirq.c
+ cc kern/trap/trap.c
+ cc kern/trap/trapentry.S
+ cc kern/trap/vectors.S
+ cc kern/mm/pmm.c
+ cc libs/printfmt.c
+ cc libs/string.c
+ ld bin/kernel
# 构建sign工具与bin/bootblock
+ cc boot/bootasm.S
+ cc boot/bootmain.c
+ cc tools/sign.c
# 使用gcc编译器由tools/sign.c生成可执行文件bin/sign
    gcc -Itools/ -g -Wall -O2 -c tools/sign.c -o obj/sign/tools/sign.o
    gcc -g -Wall -O2 obj/sign/tools/sign.o -o bin/sign
# 使用ld命令链接/boot/bootasm.o、obj/boot/bootmain.o到obj/bootblock.o
+ ld bin/bootblock
    ld -m    elf_i386 -nostdlib -N -e start -Ttext 0x7C00 obj/boot/bootasm.o 
    obj/boot/bootmain.o -o obj/bootblock.o
    'obj/bootblock.out' size: 472 bytes
    build 512 bytes boot sector: 'bin/bootblock' success!
# 构建ucore.img
dd if=/dev/zero of=bin/ucore.img count=10000 # 使用dd工具创建一个bin/ucore.img空文件
10000+0 records in
10000+0 records out
5120000 bytes (5.1 MB) copied, 0.149355 s, 34.3 MB/s
dd if=bin/bootblock of=bin/ucore.img conv=notrunc # 使用dd工具将文件bin/bootblock写入bin/ucore.img, 参数conv=notrunc表示不截断输出文件
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.0003161 s, 1.6 MB/s
dd if=bin/kernel of=bin/ucore.img seek=1 conv=notrunc # 使用dd工具将文件bin/kernel写入bin/ucore.img起始的1个block后,即bootblock后, 参数seek=1表示从输出文件开头跳过1个block开始写入
146+1 records in
146+1 records out
74923 bytes (75 kB) copied, 0.00279755 s, 26.8 MB/s

第一步.编译16个内核文件,构建出内核 bin/kernel
生成 bin/bootblock引导程序
{
编译bootasm.S,bootmain.c,链接obj/bootblock.o
编译sign.c生成sign.o工具
使用sign.o工具规范化bootblock.o,生成bin/bootblock引导扇区
}
生成ucore.img虚拟磁盘
{
dd初始化为5120000bytes,内容为0的文件
dd拷贝bin/bootblock到ucore.img第一个扇区
dd拷贝bin/kernel到ucore.img第二个扇区往后的空间
}

这个逻辑与一般的操作系统很类似

一个被系统认为是符合规范的硬盘主引导扇区的特征是什么?

上文中的sign.o工具可以规范化bootblock.o,生成bin/bootblock引导扇区。因此查看sign.c源代码内容即可
sign.c在tools里面

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
    struct stat st;
    // 输入状态判断
    if (argc != 3) {
        fprintf(stderr, "Usage: <input filename> <output filename>\n");
        return -1;
    }
    // 读取文件头
    if (stat(argv[1], &st) != 0) {
        fprintf(stderr, "Error opening file '%s': %s\n", argv[1], strerror(errno));
        return -1;
    }
    // 问题1中输出的文件大小
    printf("'%s' size: %lld bytes\n", argv[1], (long long)st.st_size);
    // 文件大小超过510字节报错返回,因为最后2个字节要用作结束标志位
    if (st.st_size > 510) {
        fprintf(stderr, "%lld >> 510!!\n", (long long)st.st_size);
        return -1;
    }
    // 多余位用0填充
    char buf[512];
    memset(buf, 0, sizeof(buf));
    FILE *ifp = fopen(argv[1], "rb");
    int size = fread(buf, 1, st.st_size, ifp);
    // 文件实际大小需和文件头描述一致
    if (size != st.st_size) {
        fprintf(stderr, "read '%s' error, size is %d.\n", argv[1], size);
        return -1;
    }
    fclose(ifp);
    buf[510] = 0x55;
    buf[511] = 0xAA;
    // 写入结束位
    FILE *ofp = fopen(argv[2], "wb+");
    size = fwrite(buf, 1, 512, ofp);
    if (size != 512) {
        fprintf(stderr, "write '%s' error, size is %d.\n", argv[2], size);
        return -1;
    }
    fclose(ofp);
    printf("build 512 bytes boot sector: '%s' success!\n", argv[2]);
    return 0;
}

硬盘主引导扇区的特征为

大小为512字节
文件内容不超过510bytes
最后2bytes为0x55 0xAA

posted @ 2020-03-29 21:58  AmosAlbert  阅读(144)  评论(0编辑  收藏  举报