在自己虚拟机里安装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函数,如图: