OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Dec 18, 2018 4:31 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Communication via serial port
PostPosted: Thu May 10, 2018 8:47 am 
Offline

Joined: Thu May 10, 2018 8:44 am
Posts: 3
Hello,

I have developed a small driver that can transmit information via the COM1 port between a small kernel and a host machine.
By telling Bochs to record what comes out of the serial port from the kernel, it works fine (so with bochs set to com1: enabled=1, mode=file, dev=serial.txt).
My goal now is to transmit information from my host machine to the kernel. I tried to write to the file without too much hope, I then tested with the use of a pipe but it just doesn't seem possible under Linux... someone to confirm? If so, is there another way? (I tested with this but strangely no error, nothing happens... com1: enabled=1, mode=pipe, dev=/tmp/myfifo).

I also checked the pic's configuration, the COM1 interrupt shouldn't be masked :
Code:
mov al, 0xEC ; ; clock, keyboard and COM1
out 0x21, al


I checked my IDT, and I found the adress of the function that should be executed (at least, a default routine could be executed... but nothing happens...) :
Code:
IDT[0x20]=32-Bit Interrupt Gate target=0x0008:0x000016b0, DPL=0 // clock (IRQ0)
IDT[0x21]=32-Bit Interrupt Gate target=0x0008:0x000016d0, DPL=0 // keyboard (IRQ1)
IDT[0x22]=32-Bit Interrupt Gate target=0x0008:0x00001690, DPL=0 // default routine
IDT[0x23]=32-Bit Interrupt Gate target=0x0008:0x00001690, DPL=0
IDT[0x24]=32-Bit Interrupt Gate target=0x0008:0x000016f0, DPL=0  // COM1 port (IRQ4)
IDT[0x25]=32-Bit Interrupt Gate target=0x0008:0x00001690, DPL=0


Have a nice day

Edit : I tried with qemu : I managed to receive a message from my kernel in my pipe, but I'm still not able to send bytes to my kernel from the host by using this same pipe...
(here is the command I used to launch qemu : qemu-system-i386 -boot a -fda floppyA -serial pipe:/tmp/myfifo)


Top
 Profile  
 
 Post subject: Re: Communication via serial port
PostPosted: Thu May 10, 2018 5:30 pm 
Offline
Member
Member
User avatar

Joined: Mon Mar 05, 2012 11:23 am
Posts: 567
Location: Germany
Hey,

how did you initialize the COM port and did you actually enable the interrupts on it? Did you try to just read something from the port without actually waiting for an interrupt to occur?

If you are sure that everything is fine and it just won't work with a pipe, you could also tell QEMU to connect to a specific TCP address, and on your local PC set up a small program that opens a server socket at that port and sends out some bytes.

_________________
-maxdev
Ghost OS / https://github.com/maxdev1/ghost


Top
 Profile  
 
 Post subject: Re: Communication via serial port
PostPosted: Fri May 11, 2018 4:33 am 
Offline

Joined: Thu May 10, 2018 8:44 am
Posts: 3
Hey !

Thank you for your answer !

I guess I did initialize the COM port correctly, here is the code :
Code:
void init_serial ()
{
    outb (COM1_PORT + 1, 0x00); // Desactive les interruptions
    outb (COM1_PORT + 3, 0x80); // Active le DLAB (Divisor Latch Access Bit)
    outb (COM1_PORT + 0, 0x03); // 38400 baud (115200 / 3), bits de poid faible
    outb (COM1_PORT + 1, 0x00); //                                       fort
    outb (COM1_PORT + 3, 0x02); // 8 bits, pas de parite, un bit de stop
    outb (COM1_PORT + 2, 0xC7);
    outb (COM1_PORT + 4, 0x0B);
}


Thank you for you idea (tcp...), I will try that this weekend !


Top
 Profile  
 
 Post subject: Re: Communication via serial port
PostPosted: Fri May 11, 2018 8:01 am 
Offline
Member
Member
User avatar

Joined: Mon Mar 05, 2012 11:23 am
Posts: 567
Location: Germany
Well not really, with this line in the start
Code:
outb (COM1_PORT + 1, 0x00);
the interrupts are disabled (as the comment behind it says)

After configuring the rest you will have to enable them again by writing the correct value to that same port, consider having a look at the documentation or this section in the wiki. Could look like this (would enable the status change interrupt):
Code:
outb (COM1_PORT + 1, 0x02);

_________________
-maxdev
Ghost OS / https://github.com/maxdev1/ghost


Top
 Profile  
 
 Post subject: Re: Communication via serial port
PostPosted: Sat May 12, 2018 3:01 am 
Offline

Joined: Thu May 10, 2018 8:44 am
Posts: 3
Thank you for your help !

I set this register to 0x02 like you suggested, and my interrupt routine linked to COM1 interrupt is executed once at the kernel launch (weird ?).
0x02 means the transmitter is empty, isn't enough to set this register correctly ?
This time, I tried with the udp protocol between netcat and qemu, and like before, I'm just able to receive bytes from the kernel but not the contrary.

Moreover, I took a look at your OS (very interesting/great :) ), and I found something weird :
Code:
/ Enable the interrupts
      // 0: 1  Receiver has data interrupt on
      // 1: 1  Transmitter empty interrupt on
      // 2: 0  Error/break interrupt off
      // 3: 0  Status change interrupt off
g_io_ports::writeByte(port + G_SERIAL_PORT_OFFSET_INTERRUPT_ENABLE, 0x02);


Why 0x02 instead of 0x03 ? (in your schema, the two first bits are set to 1 ! (anyway... it doesn't fix my problem...)


Top
 Profile  
 
 Post subject: Re: Communication via serial port
PostPosted: Mon May 14, 2018 3:29 pm 
Offline
User avatar

Joined: Mon Apr 23, 2018 6:25 pm
Posts: 15
Location: San Francisco
guidono wrote:
I set this register to 0x02 like you suggested, and my interrupt routine linked to COM1 interrupt is executed once at the kernel launch (weird ?).


It sounds like maybe you're not sending the EOI (End of Interrupt) to tell the interrupt controller that you've handled it, and are ready to receive another? See this page if you're using PIC-style interrupts.

_________________
Developing: popcorn - UEFI-booted x64 kernel


Top
 Profile  
 
 Post subject: Re: Communication via serial port
PostPosted: Tue May 15, 2018 5:50 am 
Offline
Member
Member
User avatar

Joined: Mon Mar 05, 2012 11:23 am
Posts: 567
Location: Germany
guidono wrote:
Why 0x02 instead of 0x03 ? (in your schema, the two first bits are set to 1 ! (anyway... it doesn't fix my problem...)
I think that should be 0x03 and you found a bug :mrgreen: Usually in my OS, the kernel log is written out over the serial port, and occasionally I use it to send debug data into the kernel with some software. But there I always know how many bytes will come, so I didn't need the interrupt version :P

_________________
-maxdev
Ghost OS / https://github.com/maxdev1/ghost


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group