【问题标题】:Writing on serial port COM1 in a kernel from scratch从头开始在内核中的串行端口 COM1 上写入
【发布时间】:2015-10-27 02:24:59
【问题描述】:

我正在从头开始编写 i386 ELF 内核。我需要能够写入串行端口 COM1。

我写了两个函数,每次调用printk(char* str) 时都会调用serial_init(),这会调用每个字符serial_putc(char c) 的每次迭代。

#define SERIAL_COM1 (0x03f8)

void serial_putc(char c)
{
    char* serial = (char*)SERIAL_COM1;

    while ((serial[5] & 0x20) == 0);
    serial[0] = c;
}

void serial_init()
{
    char* serial = (char*)SERIAL_COM1;

    serial[1] = 0x00;
    serial[3] = 0x80;
    serial[0] = 0x03;
    serial[1] = 0x00;
    serial[3] = 0x03;
    serial[2] = 0xc7;
    serial[4] = 0x0b;
}

线路协议为:

  • 38400 波特
  • 每个字 8 位
  • 无奇偶校验
  • 1 个停止位

我正在使用qemu-system-i386 -serial stdio -kernel ./kernel 测试我的内核,但它不会在串行端口的输出上打印任何内容。

因为我需要写outbinb,所以这里是代码:

inline void outb(unsigned int port, unsigned char val)
{
    asm volatile ("outb %%al,%%dx": :"d" (port), "a" (val));
}

inline unsigned char inb(unsigned int port)
{
    unsigned char ret;

    asm volatile ("inb %%dx,%%al":"=a" (ret):"d" (port));
    return (ret);
}

我仍然无法获得输出。
我做错了什么?

【问题讨论】:

  • 你的问题是?
  • 你用什么工具编译?你的 gcc 是为交叉编译编译的吗?
  • 这是 Debian 8 的 gcc,所以我不知道。我怎样才能找到它是否与我在串行端口上写入的问题有关(只是好奇)?

标签: c serial-port kernel i386


【解决方案1】:

你应该看看outb()和inb(),你不能这样写在你的COM1地址上。

【讨论】:

  • outb()inb() 不只是我在做什么的宏吗?尝试使用outb()inb() 时无法编译,因为我没有头文件compat/deprecated.h
  • 我已经编辑了我的帖子以添加我写的outbinb 函数。
猜你喜欢
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多