ELKS Networking --------------- Table of contents ----------------- 1. Notes on networking code 2. Setup 3. Status 1. Notes on networking code --------------------------- The current development model is based around using a user process as the actual TCP/IP stack with socket file descriptors and device drivers dealt with by the kernel. The diagram below shows how things should work. ___________________ ____________________ | | | | |Network Application| |TCP/IP stack process| |___________________| |____________________| | / | _________________|______________/____________|________________ | | / | | | KERNEL | / | | | _____|___________/_ __________|________ | | | | | | | | | TCPDEV device | | RAW Driver | | | |__________________| |___________________| | | | | |_____________________________________________|________________| | __________|________ | | | Network Hardware | |___________________| The Network Application uses the standard BSD socket interface to open, read and write sockets. The socket code passes the data on to the TCP/IP stack process (= ktcp), through the /dev/tcpdev device. ktcp then constructs TCP/IP packets and writes them to the network device driver, including all the necessary hardware headers. At system boot the code in "init/main.c" is run which calls sock_init() in "socket.c". This initializes, depending on the kernel configuration, the kernel interfaces in the files "af_init.c" (internet), "af_unix.c" (unix domain sockets) and "af_nano.c". These again call "sock_register()" in socket.c passing a structure with the functions they have implemented and their family name, e.g. "AF_INET". The common socket commands that ELKS supports i.e. socket, accept, bind, connect and listen are implemented in libc. In libc there are wrappers around kernel system calls which are implemented in "socket.c". These system calls are sys_socket, sys_accept, sys_bind, sys_connect and sys_listen. The application passes the family name with the command and this selects which of the kernel interfaces above will execute the command. You can also use the read, write, select and close commands with the socket handle. These are executed with the sock_read, sock_write, sock_select and sock_close functions in socket.c. So if the application executes a "write" with the family "AF_INET" the sock_write function in socket.c will translate this via structures of pointers into the function inet_write() in "af_inet.c" and execute that. This calls the function tcpdev_inetwrite() in our char/tcpdev driver which writes it into the "tdout_buf" buffer. This buffer is then copied to memory in the tcpdev_read() function for the ktcp user space driver to pick up and send. The ktcp driver will use the select() command to query if any data is available to send and call tcp_process() in "tcp.c" which handles the tcp connection status and calls tcp_syn_sent() which again calls tcp_output() in "tcp_output.c" which sends the data via ip_sendpacket() in "ip.c". On the other hand, the char/tcpdev driver will use the tcpdev_write() function to copy received data to the kernel interface "af_inet.c" by calling the function inet_process_tcpdev() in that code. There are two tcpdev.c files in the code. One, the "char/tcpdev", is linked as a kernel driver, and the other, "ktcp/tcpdev", handles the tcp part for the ktcp user mode driver. When ktcp is started, it initializes several modules, first it calls tcpdev_init() which is implemented in ktcp/tcpdev.c. This opens the dev/tcpdev device that the kernel mode char/tcpdev driver has provided and receives the "tcpdevfd" handle. Then the slip interface, ip, icmp, tcp and netconf are initialized. At the end ktcp calls its ktcp_run() function which does a while loop frequently calling tcp_process() in ktcp/tcpdev. The tcp_process() function queries the tcpdev device of the "char/tcpdev" driver for tasks to execute. In case of a write task, the function calls tcpdev_write which again calls tcp_output that implements retransmissions if necessary. It calls the function ip_sendpacket() in "ip.c". This function again uses the function slip_send() in "slip.c". The loop in ktcp_run() also calls slip_process() in slip.c which handles the data received by calling ip_recvpacket() in "ip.c". If an icmp packet is received by ip_recvpacket() in "ip.c" it will call icmp_process() in "icmp.c". This function just supports icmp echo to allow ELKS to reply to a ping command on the remote host. 2. Setup -------- At the moment, ELKS supports only SLIP connections so you have to connect the machine running ELKS with another machine using a serial cable. The cable required is a so-called "null modem cable". From now on, we will call the machine at the other end of the cable the gateway. Suppose that the gateway has the IP 192.168.1.1 and we like ELKS to have the IP 192.168.1.2. On the gateway we do: # slattach -p slip -L -s 9600 /dev/ttyS1 & # ifconfig sl0 192.168.1.1 pointopoint 192.168.1.2 We use /dev/ttyS1 as the serial port - replace as required. Of course, the kernel has to have slip support compiled in. This is all we need to do on the gateway. On the ELKS side, you need to have the kernel compiled with inet sockets. You also build the ktcp module found in elksnet/ktcp. You boot up ELKS and log in, then you do : # net start slip This tells ELKS to use your first serial line and that the local IP is 192.168.1.2. Note that this way the default baud rate will be used(9600bps). To change that use the stty program that comes with the elkscmd packet. # stty 1200 < /dev/ttys0 The above command will set the first serial line at 1200 bps. This is it. Ping ELKS from the gateway to see if everything is fine. * Note that if you use the disks that are created from the elkscmd package with "make images", the networking setup is much easier. Just edit the /etc/net.cfg file to enter the machine's IP and serial baud rate. 3. Status --------- This section desribes the current state of the networking code. It's purpose is to give users an idea of what is done and what to expect of the ELKS networking. Harry / Georg Potthast