【问题标题】:Printing message onto the screen using vga使用VGA将消息打印到屏幕上
【发布时间】:2018-10-14 22:41:27
【问题描述】:

我正在尝试编写一个函数,该函数将使用 VGA 文本模式缓冲区将消息打印到屏幕上。 这是打印单个字符的函数:

void putc(uint8_t c, enum Color term_color)
{
    uint8_t *vidptr = (uint8_t*)0xB8000;

    *vidptr = c;
    vidptr++;
    *vidptr = (uint8_t*)term_color;
    vidptr++;
}

这是我要打印字符串的函数:

void puts(const uint8_t* str, enum Color term_color)
{
    for(size_t i = 0; i != '\0'; i++) {
        putc(str[i], term_color);
    }
}

但它不打印任何东西。只是黑屏,光标闪烁。

编辑:打印单个字符的第一个函数有效。

【问题讨论】:

  • vidptrputc 中的局部变量,因此更改的范围仅适用于该函数执行并随后丢失时。如果将其标记为静态或将其移到 putc 函数之外会发生什么。由于它是内存映射 IO,因此您也应该使用 volatile。函数之外的 volatile uint8_t * const vidptr = (volatile uint8_t *)0xb8000 之类的东西。
  • 您的puts() 调用putc() 但这会将每个字符打印到左上角。您必须以某种方式记住在putc() 之外增加的vidptr。首先尝试使static uint8_t *vidptr = (uint8_t*)0xB8000; 理解我的意思。然后,考虑到您可能希望稍后使用 setCursor() 之类的东西(重新)将其设置为某个单元格。
  • 糟糕,在我的第一条评论中删除const。通常在显示页面 0 上使用文本模式,我有一个指向视频内存基址的主指针,该指针保持不变并跟踪全局变量中的当前 X、Y 坐标。通常更容易将文本内存视为uint16_t 甚至更好 - 一个更容易处理颜色/属性字节和颜色的结构
  • 不打印任何东西或打印在一个地方?
  • 你写的是 32 位内核还是 64 位内核?这个问题似乎无关紧要,但事实并非如此。编写 64 位内核的人通常会尝试将代码编译为 64 位,但实际上并未将处理器置于 64 位长模式。结果是 64 位代码未正确解码。通常在操作系统开发的早期表现出来,视频例程无法按预期工作。

标签: c operating-system kernel osdev vga


【解决方案1】:

功能

putc(uint8_t c, enum Color term_color)

始终将字符放在相同的位置 (0xB8000)。
你需要声明

uint8_t *vidptr

在函数外部每次调用都正确递增它。

【讨论】:

  • 比这多一点,因为他的循环是错误的for(size_t i = 0; i != '\0'; i++) 是不正确的。条件应该是for(size_t i = 0; str[i] != '\0'; i++)
  • @Michael Petch,对!我只看到了“主要”问题。这也解释了为什么没有显示字符:循环没有开始('\0' 是 0)!
猜你喜欢
  • 2023-03-14
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
相关资源
最近更新 更多