自定义内核无法在屏幕上正确打印

时间:2018-08-18 11:10:33

标签: string gcc x86 kernel osdev

我无法在自定义内核上打印字符串。我一直在关注github上的教程。到目前为止,我只能打印不超过5个字符的字符串,并且不能直接将字符串作为参数传递。

kernel.c

#include "../drivers/screen.h"

void main() {
  clear_screen();
  // This line does NOT work.
  kprint_at("X", 10, 10);

  // This line DOES work
  char msg[] = "X";
  kprint_at(msg, 10, 10);

  // This line does NOT work
  char msg[] = "123456"; // Will only work for strings less than 6 characters.
  kprint_at(msg, 10, 10);
}

screen.c

void kprint_at(char* message, int col, int row) {
  int offset;
  if (col >= 0 && row >= 0) offset = get_offset(col, row);
  else {
    offset = get_cursor_offset();
    row = get_offset_row(offset);
    col = get_offset_col(offset);
  }

  int i = 0;
  while (message[i] != 0) {
    offset = print_char(message[i++], col, row, WHITE_ON_BLACK);
    row = get_offset_row(offset);
    col = get_offset_col(offset);
  }
}

int print_char(char c, int col, int row, char attr) {
  unsigned char* vidmem = (unsigned char*) VIDEO_ADDRESS;
  if (!attr) attr = WHITE_ON_BLACK;

  if (col >= MAX_COLS || row >= MAX_ROWS) {
    vidmem[2*(MAX_COLS)*(MAX_ROWS)-2] = 'E';
    vidmem[2*(MAX_COLS)*(MAX_ROWS(-1] = RED_ON_WHITE;
    return get_offset(col, row);
  }

  int offset;
  if (col >= 0 && row >= 0) offset = get_offset(col, row);
  else offset = get_cursor_offset();

  if (c == '\n') {
    row = get_offset_row(offset);
    offset = get_offset(0, row+1);
  } else {
    vidmem[offset] = c;
    vidmem[offset+1] = attr;
    offset += 2;
  }
  set_cursor_offset(offset);
  return offset;
}

如果我将行或列设置为超出屏幕的宽度或高度,我的确会在右下角看到一个红色的E,因此我知道这正常工作。另外,如果我将单词设置为在屏幕结尾附近开始,则该单词会在下一行继续。它只是不允许我将字符串直接输入到kprint_at函数中,也不允许我使用任何大于5个字符的字符串。有什么想法吗?

我正在使用带有汇编语言的c语言。我也使用64位linux系统,但是我以32位保护模式运行内核。使用gcc交叉编译器(i386-elf-gcc)。

0 个答案:

没有答案