The gumstix.org wiki has a page on how to configure your gumstix to auto-login on boot. This can be very nice for “production” systems where the intention is to power on and run some specific firmware/code every time.
However, with the new Yocto/Poky images based on the 3.5 kernel, things have changed and the old instructions no longer work. Here is a quick recipe to get autologin running again on the newer systems. First of all credit to http://fedoraproject.org/wiki/Systemd for their section on setting up autologin on a virtual terminal with the new systemd architecture.
Step #1:
Compile this “autologin.c” program and install it to /sbin/autologin (make sure you have executable permissions, etc. etc.)
#include <unistd.h> #include <stdio.h> #include <string.h> int main() { int nrv = 0; FILE* fptr = 0; char user[64]; // clear buffer memset(user,'\0',64); // open autologin profile file fptr = fopen("/etc/autologin.profile\0","r\0"); // make sure the file exists and was opened if (fptr != 0) { // the return value from fscanf will be 1 if the autologin profile name is read correctly nrv = fscanf(fptr,"%s\0",user); } // only autologin if the profile name was read successfully, // otherwise show the regular login prompt if (nrv > 0) nrv = execlp("login\0","login\0","-f\0",user,0); else nrv = execlp("login\0","login\0","\0",0,0); return 0; } |
Step #2
Create the /etc/autologin.profile file by running:
echo "root" > /etc/autologin.profile
The autologin program looks for this file to determine which user id should be autologged in.
Step #3
Setup the systemd configuration.
cp /lib/systemd/system/serial-getty@.service /etc/systemd/system/autologin@.service ln -sf /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/serial-getty@ttyO2.service cd /etc/systemd/system/getty.target.wants/ vi serial-getty@ttyO2.service |
Next, change the line that reads”
ExecStart=-/sbin/agetty -s %I 115200 |
to read:
ExecStart=-/sbin/agetty -n -l /sbin/autologin -s %I 115200 |
Troubleshooting
- If you still get a login prompt, make sure you created the /etc/autologin.profile file correctly, the autologin program needs that or it will just execute a standard login prompt.
Step #4
You may find yourself in a situation where you may not always want your code executed automatically. You may want an option to “break in” and get a prompt. There are many ways you could do this, but here’s one simple way:
Compile the “pressanykey.c” code and install the executable in /sbin/pressanykey
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <termios.h> #include <unistd.h> int kbhit(void) { fd_set rfds; struct timeval tv; int retval; struct termios term, oterm; int fd = 0; tcgetattr( fd, &oterm ); memcpy( &term, &oterm, sizeof(term) ); cfmakeraw(&term); tcsetattr( fd, TCSANOW, &term ); /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to one seconds. */ tv.tv_sec = 1; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Don't rely on the value of tv now! */ tcsetattr( fd, TCSANOW, &oterm ); return(retval); } int mygetch( ) { struct termios oldt, newt; int ch; tcgetattr( STDIN_FILENO, &oldt ); newt = oldt; newt.c_lflag &= ~( ICANON | ECHO ); tcsetattr( STDIN_FILENO, TCSANOW, &newt ); ch = getchar(); tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); return ch; } int main(int argc, char **argv) { int count = 5; if ( argc > 1 ) { int tmp = atoi(argv[1]); if ( tmp > 0 ) { count = tmp; } } printf("Press any key ... "); fflush(stdout); while ( count >= 0 ) { printf("%d ", count); fflush(stdout); //int result = mygetch(); if ( kbhit() ) { return 1; } //sleep(1); count--; } return 0; } |
Next create a ~/.profile file that includes the following:
/sbin/pressanykey 5
if [ $? != 0 ]; then
echo "Starting interactive shell"
else
echo "Continuing with default"
/path/to/my/code
fi |
Now, along with autologging in as root (or which every user you specified) you will then be presented with a count down timer similar to the “u-boot” timer where you can press any key to get a shell prompt, or continue to your firmware code if no interaction is required.
