跟我一起写操作系统(三)——打印函数和qemu虚拟机

转载注明出处:http://www.cnblogs.com/lucasysfeng/p/4847662.html

  上一讲地址:http://www.cnblogs.com/lucasysfeng/p/4847662.html

  项目地址:https://github.com/lucasysfeng/lucasOS

  

  本讲主要涉及以下三个方面:1. 打印函数封装;2. qemu的使用;3. 项目目录结构调整。 理由如下:1. 后续开发无疑会遇到打印变量的操作,因此有必要封装打印函数(内核开发阶段,无法调用库函数);2. 前两节,我们都是生成镜像文件,然后由VMvare启动,过程较繁琐,后续我们使用qemu虚拟机,可以直接在Linux环境下启动qemu;3. 随着项目的复杂,有必要调整目录结构,并调整Makefile.

  本讲没有过多讲解,看代码完全可以理解。本讲只是列出了部分代码,全部代码对应https://github.com/lucasysfeng/lucasOS上的code/chapter3.

 

清屏


  0xb8000h是显存开始的地址,因此打印就是操作0xb8000h开始的地址,从0xb8000h这个地址开始,每2个字节表示一个字符,前一个字节是字符的ASCII码,后一个字节是这个字符的颜色和属性。

  lib/kprint.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 一屏25行
#define LINE_COUNT 25
// 一行80个字符
#define LINE_LENGTH 80
// 字符颜色
#define COLOR 0x04
 
// 显存开始地址
static  unsigned  short  *display_buf = (unsigned  short  *) 0xb8000;
// 字符属性
static  const  unsigned  short  char_attr = COLOR << 8;
 
// 当前光标的坐标
static  unsigned  char  cursor_x = 0;
static  unsigned  char  cursor_y = 0;
 
/**
  * 清屏
  */
void  print_clear()
{
     unsigned  int  i;
     for  (i = 0; i < LINE_COUNT * LINE_LENGTH; i++)
     {
         display_buf[i] = 0x20 | char_attr;
     }
 
     cursor_x = 0;
     cursor_y = 0;
}

  

打印字符


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
  * 打印一个字符(为简化逻辑,某些特殊字符均作为换行符处理)
  */
void  print_char( const  char  c)
{
     if  (c >=  ' ' )
     {
         display_buf[cursor_y * LINE_LENGTH + cursor_x] = c | char_attr;
         cursor_x++;
     }
     else
     {
         cursor_x = 0;
         cursor_y++;
     }
 
     // 每行80个字符,满80个字符换行
     if  (cursor_x >= 80)
     {
         cursor_x = 0;
         cursor_y++;
     }
 
     scroll();   // 满一屏时,向上滚屏
}

 

打印字符串


  调用打印字符函数。

1
2
3
4
5
6
7
8
9
10
/**
  * 打印以\0结尾的字符串
  */
void  print_str( const  char * str)
{
     while  (*str)
     {
         print_char(*str++);
     }
}

 

内核入口


   print_dec()   print_hex()在github上,此处没给出实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "kprint.h"
 
int  kernel_main()
{
     print_clear();
 
     print_str( "hello world, print is OK\n" );
     print_dec(123);
     print_char( '\n' );
     print_dec(-123);
     print_char( '\n' );
     print_hex(11);
 
     return  0;
}

 

编译和运行


   我们使用qemu启动虚拟机,所以先要安装qemu,qemu的安装和使用此处略。

$ make

$ make qemu 

  make后会生成kernel内核,并将内核拷贝到lucasOS.img中,运行make qemu就会加载lucasOS.img,并出现下面窗口,表示成功了:        

代码获取

猜你喜欢

转载自blog.csdn.net/zashizhi3299/article/details/80870103