Newsgroup: it.comp.os.linux.development
Titolo: Seriale e kernel modules

Mi servirebbe inviare informazioni di debug attraverso la seriale
collegata con un nullmodem ad un altro pc in ascolto.
Il problema e' che non posso utilizzare le normali chiamate
open("/dev/ttyS0") perche' sono dentro a un modulo realtime. Per di piu'
l'uso di chiamate al kernel stesso puo' portare a guai vari.
Quello che volevo era mandare brevi messaggi utilizzando solo le
funzioni outb/inb, permettendomi di seguire dall'altro pc il
comportamento della macchina, anche se questa si dovesse bloccare
improvvisamente prima di salvare su disco quanto passato a printk.
E' necessario quindi avere l'invio bloccante delle informazioni
attraverso la seriale.
Mi basterbbe avere qualcosa del tipo "invia_byte(char c)"
Qualche consiglio?
Saluti
	ZioCantante

 collegata con un nullmodem ad un altro pc in ascolto.
[...]
Ho risolto

Zio Cantante wrote:

se a questo punto ci dici pure come ...


Certo, vi "pasto" il codice che ho utilizzato.
E' preso da una patch per grub per il supporto della seriale.
La funzione da usare e' serial_putchar.
#define COMPARAMS  0x03  /* 8,n,1     */
//#define BAUDDIV    12    /* 9600 baud */
#define BAUDDIV    1    /* 115200 baud */
#define COMPORT    0x3f8 /* ttyS0     */
#define OUTB outb_p
static unsigned serport = 0;
static int serial_init (unsigned short);
static void serial_putc (int);
/* serial i/o functions */
static void 
serial_putc (int c)
{
  int timeout;
 
  if (serport == 0)
    serial_init (COMPORT);
 
  /* timout value is derived from the etherboot's serial.S  */
  timeout = 10000;
  /* wait for an empty TX buffer */
  while ((timeout > 0) && ((inb (serport + 5) & 0x20) == 0))
    timeout--;
  OUTB ((unsigned char) c, serport);
}
static int
serial_init (unsigned short port)
{
  unsigned short bdiv = 0;
  unsigned char b;
 
  if (port == 0)
    return -1;
 
  bdiv = BAUDDIV;
 
  /* enable DLAB */
  OUTB (0x80, port + 3);
 
  /* write low & high byte of bdiv, abd readback to check,
     if device is present */
  b = (unsigned char)(bdiv & 0xffu);
  OUTB (b, port);
  if (inb (port) != b)
    return -1;
 
  b = (unsigned char)(bdiv >> 8);
  OUTB (b, port + 1);
  if (inb (port + 1) != b)
    return -1;
 
  /* ok, device is found and baudreae set */
  serport = port;
  /* disable fifo */
  OUTB (0x00, port + 2);
 
  /* set line control reg to data bits, parity and stop bits */
  OUTB (COMPARAMS, port + 3);
 
  /* set modem controls, enable DTR, RTS */
  OUTB (0x03, port + 4);
 
  /* flush the input buffer */
  while (inb (port + 5) & 0x01)
    b = inb (port);    /* dummy read */
 
  return 0;
}
void
serial_putchar (int c)
{
  /* do a vt100 like onlcr, instert a cr before new line */
  if (c == 0x0a)
    serial_putc (0x0d);
  serial_putc (c);
}
A questo punto pero' ho un nuovo problema.
Riesco a ricevere i messaggi della mia applicazione, ma non so come fare
per salvare in qualche modo il testo che compare quando succede qualche
catastrofe nel kernel.
Spesso riesco a leggere l'intero messaggio sullo schermo della
postazione, ma a volte mi capita che il messaggio di errore sia molto
lungo e la prima parte di tale messaggio non stia nello schermo.
Come posso fare per redirigere tale output su seriale o file ?

 Come posso fare per redirigere tale output su seriale o file ?
tee </dev/ttySx file-di-log
cosi hai i log sia sul file "file-di-log" sia a console. Al limite puoi 
chiudere una seriale sull'altra cosi' puoi usare lo stesso picci 


C'e' il problema che tipicamente quando arrivo a una schermata con
scritto qualche "oops", la macchina su cui si verifica e' totalmente
inchiodata, per cui le info di tale oops non sono memorizzate da nessuna
parte.

 parte.
Se la macchina si blocca non hai speranza di salvarle sulla stessa macchina 
complice la latenza dovuta alla cache del VFS...
L'unica e' provare con due macchine ....