Page 1 of 2
Serial port outputs random data
Posted: Sun Aug 28, 2016 2:39 pm
by Ycep
Hi, I was recently writing my Serial Port Driver, and it seems to output random data.
When I try to send character 'X', I get 0x18.
This is my SendSerial function. ex. SendSerial(0,'X');
Code: Select all
void SendSerial(uint8 COM, uint8 data)
{
if(COM>SerialComAmount-1)
{
if(SerialComAmount==0)cerror("No Serial Hardware in System.");
else cerror("Can't use unregistered serial port!");
return;
}
uint16 SerAddr=SerialPort[COM];
while(!(inb(SerAddr+5)&0x20));
outb(SerAddr,data);
}
Bochs and VMWare just output 0x18 rather than 0x58 on serial port.
InitSerial():
Code: Select all
bool InitSerial()
{
for(uint8 i=0;i<4;i++)
{
uint16 val=*((uint16*)(0x0400+i*2));
if(!val)continue;
SerialPort[i]=val;
SerialComAmount++;
InitPort(val);
}
printf("\nSerial Ports:%d\n",SerialComAmount);
if(SerialComAmount)return true;
else return false;
}
SetBaud (Function for setting baud) and InitPort:
Code: Select all
void SetBaud(uint16 portaddr,uint8 divisor)
{
outb(portaddr+3,0x80);
outb(portaddr,divisor);
outb(portaddr+1,0);//I will not use divisors bigger than 255
}
void InitPort(uint8 portaddr)
{
outb(portaddr+1,0x00);
SetBaud(portaddr,3);
outb(portaddr,0x03);//0000 0011
outb(portaddr+2,0xC7);
outb(portaddr+4,0x0B);
}
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:01 pm
by Octacone
Your code seems overly complex. (I use something much simpler, personal preference)
Try this:
Code: Select all
outportb(COM1, 'o');
//com1 is 0x3F8
and tell me the output.
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:11 pm
by Ycep
octacone wrote:Your code seems overly complex.
Try this:
Code: Select all
outportb(COM1, 'o');
//com1 is 0x3F8
and tell me the output.
0x0F. Again random.
It isn't complex. It only has support for multiple serial ports, serial port address detection, etc. Nothing complex, I'll rather refer it simple.
Thanks for suggestion.
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:15 pm
by Octacone
Lukand wrote:octacone wrote:Your code seems overly complex.
Try this:
Code: Select all
outportb(COM1, 'o');
//com1 is 0x3F8
and tell me the output.
0x0F. Again random.
It isn't complex. It only has support for multiple serial ports, serial port address detection, etc. Nothing complex, I'll rather refer it simple.
Thanks for suggestion.
What!? That is not what I expected. Give me a moment.
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:16 pm
by phredreeck
Hmm, your code seems OK. Could you show your outb() function?
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:18 pm
by Octacone
@f2
This is the one I use:
Code: Select all
void outportb(uint16 _port, uint8 _data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Works perfectly fine, he can try it out.
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:19 pm
by Ycep
f2 wrote:Hmm, your code seems OK. Could you show your outb() function?
No problem. Why is it needen? It's working flawlessly for everything else:
Code: Select all
void outb(uint16 prt, uint8 val)
{
_asm
{
mov al, byte ptr[val]
mov dx, word ptr[prt]
out dx, al
}
}
octacone wrote:@f2
This is the one I use:
Code: Select all
void outportb(uint16 _port, uint8 _data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Works perfectly fine, he can try it out.
Eh...

. I don't want to, since that is GCC compilant. Please do not make fool from me. Do you really think that my outb() code isn't working?
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:24 pm
by Octacone
So did it work?
Edit: what emulator do you use?
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:26 pm
by Ycep
octacone wrote:So did it work?
Edit: what emulator do you use?
I said I tried it on VMWare and Bochs.
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:27 pm
by Octacone
Lukand wrote:octacone wrote:So did it work?
Edit: what emulator do you use?
I said I tried it on VMWare and Bochs.
Try Qemu with and don't forget std -serial stdio
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:31 pm
by Ycep
octacone wrote:Lukand wrote:octacone wrote:So did it work?
Edit: what emulator do you use?
I said I tried it on VMWare and Bochs.
Try Qemu with and don't forget std -serial stdio
I am using MS Windows. QEMU is Linux emulator. And if it won't work on VMWare and Bochs what is the purpose then?
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:37 pm
by phredreeck
OK, so your outb() seems correct.
I just found something in your InitPort() function I haven't seen before.
Look at this code from OSDev Wiki (
http://wiki.osdev.org/Serial_Ports#Example_Code ):
Code: Select all
#define PORT 0x3f8 /* COM1 */
void init_serial() {
outb(PORT + 1, 0x00); // Disable all interrupts
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(PORT + 1, 0x00); // (hi byte)
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
}
If I compare it with your code:
Code: Select all
outb(portaddr+1,0x00);
SetBaud(portaddr,3);
outb(portaddr,0x03);//0000 0011
outb(portaddr+2,0xC7);
outb(portaddr+4,0x0B);
I see on the third line that you are sending the value
0x03 to
portaddr and not to
portaddr + 3, as you can see in the init_serial() function.
Can you change the line
outb(portaddr,0x03) to
outb(portaddr+3,0x03) and see if that fixes your problem?
EDIT: removed a comma, thanks octacone

Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:39 pm
by Octacone
f2 wrote:
Can you change the line outb(portaddr,0x03) to outb(portaddr,+3,0x03) and see if that fixes your problem?
outb(portaddr,+3,0x03) -> outb(portaddr+3,0x03)
Edit: @f2

Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:42 pm
by BrightLight
Lukand wrote:I am using MS Windows. QEMU is Linux emulator.
QEMU is by no means tied to Linux. A quick Google search "QEMU on Windows" will get you good results.
The code snippets on the serial port Wiki page are enough to properly initialize the serial port.
Code: Select all
void com1_init()
{
short* com1_bda = (short*)0x400;
com1_base = com1_bda[0];
if(com1_base == 0) return; // if there is no serial port, there's nothing to do
outb(com1_base+1, 1);
iowait();
outb(com1_base+3, 0x80);
iowait();
outb(com1_base+0, 2);
iowait();
outb(com1_base+1, 0);
iowait();
outb(com1_base+3, 3);
iowait();
outb(com1_base+2, 0xC7);
iowait();
dprintf(KERNEL_STRING);
dprintf("\n");
dprintf("com1: initialized serial port, base IO port is at 0x%x.\n", com1_base);
}
void com1_send_byte(char byte)
{
if(com1_base == 0) return;
while(!(inb(com1_base+5) & 0x20));
if(byte == '\n')
{
while(!(inb(com1_base+5) & 0x20));
outb(com1_base, 13); // carriage
while(!(inb(com1_base+5) & 0x20));
outb(com1_base, 10); // newline
while(!(inb(com1_base+5) & 0x20));
return;
}
outb(com1_base, byte);
while(!(inb(com1_base+5) & 0x20));
}
Re: Serial port outputs random data
Posted: Sun Aug 28, 2016 3:45 pm
by iansjack
'X' = 0x58, you get 0x18
'o' = 0x6F, you get 0x0F
Do you spot the pattern? You haven't set the number of data bits, so it looks like it has defaulted to 5 bits rather than 7 or 8.