Yes, I've called the _io.run() into my SerialPort constructor, but I think it end immediately because it has no work to do!!
Yes, if the io_service has no work, its main loop exits. If you want it to keep running without "real" work, you can associate io_service with asio::work object (see examples).
In my SerialPort class the reading method is called in a separate thread when I open the device and it doesn't return until I stop it:
_thread.reset( new boost::thread( boost::bind(&SerialPort::reading, this)) );
using asio I think I have to 'bind' it to io_service::run so when I call _io.run() it call SerialPort::reading, but how?!
If reading() is the thread function that performs actual i/o on a serial port, certainly you can't associate that thread with io_service::run. But you can start another thread for io_service(s). By the way, wouldn't it be more simple and robust to use convenient asio async. i/o objects, instead of trying to mix the asio and your own approaches?