Page 1 of 1
can't get COM1 working
Posted: Wed Jun 30, 2021 2:56 pm
by 000Zer000
Hi, I'm new to this forum, so if I'm doing anything wrong, just tell me.
I can't get a proper logging to COM1, The problem (I think) is that it is virtualized, I used the code in
https://wiki.osdev.org/Serial_Ports
After the code exits, There is nothing sent to the other side (or the other side doesn't receive it), So I went around and found other people having some problems, (i mean
viewtopic.php?f=1&t=29086,
viewtopic.php?f=1&t=30753 and
viewtopic.php?t=31374&p=271838)
And one other topic, which i wasn't able to find the link to it, But NONE of them work, Whenever i try to initialize that serial port, it breaks and nothing is sent to the other side, if i don't initialize it, it receive data but its 0x18 (surely not my logs!), What am i missing?
Re: can't get COM1 working
Posted: Wed Jun 30, 2021 8:07 pm
by indigo256
Just to be sure, could you post the code you use for your COM port?
Also, I assume you mean you're using a virtual machine. What are you using? I only have experience with qemu, so if you're running on that, I might be able to help if you send over the command you use to launch it.
If not, I'm sure someone else more experienced in what you're using can help if you post a config.
Re: can't get COM1 working
Posted: Wed Jun 30, 2021 10:07 pm
by 000Zer000
Well, I take the COM port from the bios (using the same code in osdev about its BDA), On qemu, COM1 port is 0 (even when i use -serial file:com1.log), so on qemu, nothing should work (assuming that really old qemu on ubuntu repository (4.1)), my most concern is why it doesn't work even in a virtual machine (using vmware), On vmware, When I go to the details section of virtual machine, it says there is a virtual serial port
The command for qemu is:
qemu-system-i386 -kernel bin/kernel -serial file:com1.log
And I use grub-mkrescue to supply a bootloader for my "kernel"
I think for the code, You gotta wait a little bit more (sorry), I worked with compiler definitions a lot in my currently-non-working driver, So i gotta assemble everything to each other and post it
Re: can't get COM1 working
Posted: Wed Jun 30, 2021 10:27 pm
by 000Zer000
Code: Select all
int init_com1(int rate)
{
short *_coms = ((short *)0x400);
short _com1 = _coms[0];
if(_com1 == 0)
{
// There is no COM1 for us, Report this
return 2;
}
uint8_t LOW_RATE = (uint8_t)((115200 / rate) & 0xFF);
uint8_t HIGH_RATE = (uint8_t)((115200 / rate) >> 8);
outb(_com1 + 1, 0x00);
outb(_com1 + 2, 0x04);
outb(_com1 + 3, 0x80);
outb(_com1 + 0, LOW_RATE);
outb(_com1 + 0, HIGH_RATE);
outb(_com1 + 3, 0x08 | 0x00 | 0x00); // Which is ineffective (the result is still 8), compiler will optimize it
outb(_com1 + 2, 1 | 4 | 0);
outb(_com1 + 4, (1 | 2 | 4));
outb(_com1 + 1, 0xF);
inb(_com1 + 9); // Taken from the Linux kernel
return 0;
}
This is the way i call it:
I haven't done anything fancy for inb and outb, the "usual" implementation of them.
I tried passing other rates to it, (i tried 2 and 3), When the above code runs, Nothing is received on the other side, But if I just don't call it, 534 of 0x18 is received (I checked, That's exactly the same count of my "logs"),
On qemu, It returns 2 (as it finds _com1 is 0, which tells us there is no COM1), But in vmware, it initializes but again, the problem i told above^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Re: can't get COM1 working
Posted: Wed Jun 30, 2021 11:20 pm
by 000Zer000
btw, I check
viewtopic.php?f=1&t=37400, The strings are there in .rodata (i dumped the .rodata section using objcopy --dump-section .rodata=rodata.elf), And the strings are there, It's two days that I'm on this
Re: can't get COM1 working
Posted: Thu Jul 01, 2021 12:12 am
by klange
000Zer000 wrote:On qemu, It returns 2 (as it finds _com1 is 0, which tells us there is no COM1), But in vmware, it initializes but again, the problem i told above^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Instead of trying to use the BIOS Data Area, which may not exist - and is even less likely to exist when you booted from GRUB via Multiboot as maintaining it is not in the spec - have you considered hardcoding the well-known fixed port addresses for the serial controller?
Re: can't get COM1 working
Posted: Thu Jul 01, 2021 12:31 am
by 000Zer000
Wait BDA isn't guaranteed to exist? Where else should we get those info from? (assuming we are booting from BIOS, as there is currently no support for UEFI, my kernel is pretty much basic), anyway, i tried hard coding it (to 0x3F8), that didn't work either, It had the same results as getting the address from BDA.
Is everything fine with the code?
Re: can't get COM1 working
Posted: Thu Jul 01, 2021 5:28 am
by nexos
The standard method of getting the COM1 base is using ACPI, but that is very complicated. For now, just hardcode 0x3F8 as the COM1 base. On most hardware I've seen (and QEMU), that works.
Re: can't get COM1 working
Posted: Thu Jul 01, 2021 12:32 pm
by Octocontrabass
You're writing the divisor high byte to the port for the divisor low byte.
Code: Select all
outb(_com1 + 3, 0x08 | 0x00 | 0x00); // Which is ineffective (the result is still 8), compiler will optimize it
Why are you selecting 5O1 instead of the much more common 8N1? You'll have a hard time fitting ASCII into 5 bits.
Code: Select all
inb(_com1 + 9); // Taken from the Linux kernel
Where in the Linux kernel?
You can't program a high enough divisor to set the baud rate to 1, and I can't imagine such a low baud rate being useful anyway. Try something like 9600 instead.
000Zer000 wrote:I haven't done anything fancy for inb and outb, the "usual" implementation of them.
Can't hurt to post them anyway.