Re: porting linux 2.6.18.1(EABI) support GCC-4.1.1(eabi) shell not coming
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: porting linux 2.6.18.1(EABI) support GCC-4.1.1(eabi) shell not coming



On Friday 16 February 2007 11:44, satpal parmar wrote:
> Hi all ;
> 
>  I am facing some  problem in porting linux kernel 2.6.18. I went through
> some mailing list,archives and find mails refering exactly the problem I am
> facing but unfortunetly I didnt get any working hints or solutions.I am
> wondering if what I am facing is a known issue for embeded community. I
> apprecaite if someone can  share hsi/her experinece on this isue.
> 
> *Problem:* We are porting linux-2.6.18.2 on ARM based chip, with
> toochain-4.1.1(EABI), software floating point and uClibc-0.9.28.1.
> We are using busybox-1.2.2.1 and ash shell.I am facing a certain problem in
> init.c, before the shell comes up.
> 
> I have traced the problem and it seems to be that i don't recover from
> the function console_init (in file init.c) .

That's why I keep saying "you don't need any stinking init,
shell script will suffice". Because init has some really obscure
and ugly code (even our own init, which is *supposed to be*
small and simple).

Here we go:

static char console[CONSOLE_BUFF_SIZE] = "/dev/console";
static const char *log_console = VC_5;

static void console_init(void)
{
        int fd;
        int tried = 0;
        struct vt_stat vt;
        struct serial_struct sr;
        char *s;

        if ((s = getenv("CONSOLE")) != NULL || (s = getenv("console")) != NULL) {
                safe_strncpy(console, s, sizeof(console));
        } else {
                /* 2.2 kernels: identify the real console backend and try to use it */
                if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
                        /* this is a serial console */
                        snprintf(console, sizeof(console) - 1, SC_FORMAT, sr.line);
                } else if (ioctl(0, VT_GETSTATE, &vt) == 0) {
                        /* this is linux virtual tty */
                        snprintf(console, sizeof(console) - 1, VC_FORMAT, vt.v_active);
                } else {
                        safe_strncpy(console, "/dev/console", sizeof(console));
                        tried++;
                }
        }

        while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0 && tried < 2) {
                /* Can't open selected console -- try logical system console and VT_MASTER */
                safe_strncpy(console, (tried == 0 ? "/dev/console" : "/dev/tty0"), sizeof(console));
                tried++;
        }
        if (fd < 0) {
                /* Perhaps we should panic here? */
#if !ENABLE_SYSLOGD
                log_console =
#endif
                safe_strncpy(console, bb_dev_null, sizeof(console));
        } else {
		... set TERM ...
		close(fd)
	}
}

int init_main(int argc, char **argv)
{
 ...a few irrelevant things skipped...
        /* Figure out where the default console should be */
        console_init();
        /* Close whatever files are open, and reset the console. */
        close(0);
        close(1);
        close(2);
        if (device_open(console, O_RDWR | O_NOCTTY) == 0) {
                set_term();
                close(0);
        }

<bitching>
Hello? What a fsck is going on here? Why we are closing perfectly
fine open stdio desriptors which kernel gave us?
init=/bin/sh manages to work without such idiosyncrasies, why
we need a pile of this code - just for setting TERM?
</bitching>

After some grepping around:

console is = getenv("CONSOLE"/"console"), "/dev/console", "/dev/tty0"
or "/dev/null". It is used only in two places: in init_main
(shown above) and in new_init_action() is cons is "":

static void new_init_action(int action, const char *command, const char *cons)
{
        struct init_action *new_action, *a, *last;
        if (*cons == '\0')
                cons = console_name;

[cons subsequently ended up in init_action::terminal and
is used for open() and access() - not too hard to adapt
those places for just dup()ing fd#0 if we will want to fix the mess...]

Also note that 'console' is an awful variable name - grepping for it
is bound to produce tons of false positives. I think console_name is better.

log_console is vt#5 unless we failed to open getenv("CONSOLE"/"console"),
"/dev/console" and "/dev/tty0" (then console = "/dev/null"),
or if opened console turned out to be a serial line (in that case
log_console = console). log_console is used only by
message(LOG, ...) in init.c, nowhere else.

This is awfully messy.

> VFS: Mounted root (ext2 filesystem) readonly.
> Freeing init memory: 68K
> Hello WOrld inside init.c
> before console_init
>  (no shell)
> Thanks for your patience and time.
> 
> Regards
> satpal

satpal, any chance you can pinpoint what exactly is failing
in init_console?
--
vda