2019-2020-1 20209319《Linux内核原理与分析》第四周作业

在自己虚拟机里安装menuos

首先下载Linux内核源码,然后对内核源码进行编译,效果如图:

然后下载menuos源码,创建rootfs文件,接着下载aqemu和qemu,用qemu命令运行Linux内核,效果如图:

代码如下
获得内核并且编译mkdir LinuxKernel cd LinuxKernel wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz xz -d linux-3.18.6.tar.xz tar -xvf linux-3.18.6.tar cd linux-3.18.6 make i386_defcongig make
获得menu并且制作镜像文件mkdir rootfs git clone https://github.com/mengning/menu.git cd menu gcc -pthread -o init linktable.c menu.c test.c -m32 -static cd ../rootfs cp ../menu/init ./ find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img
安装qemusudo apt-get install qemu
安装aqemusudo apt-get install aqemu
设置链接sudo ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu
启动内核qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

在Linux内核中添加hello命令

接下来是为我们的内核添加hello+学号的命令:
我们给/menu文件夹中的test.c文件中添加如下代码:

#include <stdlib.h>
#include <time.h>
#include "menu.h"

#define FONTSIZE 10
int PrintMenuOS()
{
    int i, j;
    char data_M[FONTSIZE][FONTSIZE] =
    {
        "          ",
        "  *    *  ",
        " ***  *** ",
        " * *  * * ",
        " * *  * * ",
        " *  **  * ",
        " *      * ",
        " *      * ",
        " *      * ",
        "          "
    };
    char data_e[FONTSIZE][FONTSIZE] =
    {
        "          ",
        "          ",
        "    **    ",
        "   *  *   ",
        "  *    *  ",
        "  ******  ",
        "  *       ",
        "   *      ",
        "    ***   ",
        "          "
    };
    char data_n[FONTSIZE][FONTSIZE] =
    {
        "          ",
        "          ",
        "    **    ",
        "   *  *   ",
        "  *    *  ",
        "  *    *  ",
        "  *    *  ",
        "  *    *  ",
        "  *    *  ",
        "          "
    };
    char data_u[FONTSIZE][FONTSIZE] =
    {
        "          ",
        "          ",
        "  *    *  ",
        "  *    *  ",
        "  *    *  ",
        "  *    *  ",
        "  *    *  ",
        "   *  **  ",
        "    **  * ",
        "          "
    };
    char data_O[FONTSIZE][FONTSIZE] =
    {
        "          ",
        "   ****   ",
        "  *    *  ",
        " *      * ",
        " *      * ",
        " *      * ",
        " *      * ",
        "  *    *  ",
        "   ****   ",
        "          "
    };
    char data_S[FONTSIZE][FONTSIZE] =
    {
        "          ",
        "    ****  ",
        "   **     ",
        "  **      ",
        "   ***    ",
        "     **   ",
        "      **  ",
        "     **   ",
        "  ****    ",
        "          "
    };

    for(i=0; i<FONTSIZE; i++)
    {
        for(j=0; j<FONTSIZE; j++)
        {
            printf("%c", data_M[i][j]);
        }
        for(j=0; j<FONTSIZE; j++)
        {
            printf("%c", data_e[i][j]);
        }
        for(j=0; j<FONTSIZE; j++)
        {
            printf("%c", data_n[i][j]);
        }
        for(j=0; j<FONTSIZE; j++)
        {
            printf("%c", data_u[i][j]);
        }
        for(j=0; j<FONTSIZE; j++)
        {
            printf("%c", data_O[i][j]);
        }
        for(j=0; j<FONTSIZE; j++)
        {
            printf("%c", data_S[i][j]);
        }
        printf("
");
    }
    return 0;
}

int Quit(int argc, char *argv[])
{
    /* add XXX clean ops */
}

int Time(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    tt = time(NULL);
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d
",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}

int TimeAsm(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    asm volatile(
        "mov $0,%%ebx
	"
        "mov $0xd,%%eax
	" 
        "int $0x80
	" 
        "mov %%eax,%0
	"  
        : "=m" (tt) 
    );
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d
",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}
int hello(int argc, char *argv[])
{
	
	printf("hello 20209319");
}
int main()
{
    PrintMenuOS();
    SetPrompt("MenuOS>>");
    MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
    MenuConfig("quit","Quit from MenuOS",Quit);
    MenuConfig("time","Show System Time",Time);
    MenuConfig("time-asm","Show System Time(asm)",TimeAsm);
    MenuConfig("hello","hello 20209319",hello);
    ExecuteMenu();
}

代码添加后直接在menu目录编译运行,输入 make rootfs 命令来运行内核,结果如图:

可以看到我们的hello+学号的命令已经添加完成。

调试Linux内核

接下来可以分析内核源代码,使用 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s 命令来运行内核以调试模式,并且以1234端口连接,接下来我们打开gdb输入一下命令:

target remote:1234

并且使用 b start_kernel 在内核处下断点,按r进行运行程序在strat_kernel处断下。
我们可以看下strat_kernel的源代码,效果如图:

还可以在里面找到rest_init函数,如图:

原文地址:https://www.cnblogs.com/ring3toring0/p/13908753.html