Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Mar 2001 11:34:17 -0500
From:      "Patrick Bihan-Faou" <patrick@netzuno.com>
To:        <freebsd-stable@freebsd.org>
Subject:   Re: Problem with bootable CD...
Message-ID:  <HJEEKLMFLKEOKHOKNPBMOEJPCLAA.patrick@netzuno.com>

next in thread | raw e-mail | index | archive | help
Hi all,


Well I got no answer from this list whatsoever, but I managed to finally
solve the problem.

The issue was that the decompression of the kernel was not happening
correctly at load time. For some reason (that I am not going to explore),
while decompressing the text segment of the kernel, the loader would read
more data that was really necessary. This would cause the current position
in the compressed stream to be a bit further than the start of the data
segment. When the loader then tries to decompress the data segment, it
performs a lseek to the start of it (which in normal situation should be a
noop since the stream is already in that position). Because it is not
possible to seek backward in a compressed stream, the lseek call fails and
the load terminates with errno=94 (== EOFFSET in libstand).

The way I solved this was by using the default compression factor to create
the compressed kernel (i.e. gzip kernel, rather than gzip -9 kernel). The
difference in size is negligeable (< 5k for a 1.7Mg compressed file) and the
"less" compressed kernel loads fine.

This may be an issue for other people who build bootable CDs. I took example
on what is done in /usr/src/release. This is where I copied the code that
does a "gzip -9". It might be a good idea to drop the -9 option as it does
not save anything and can create problems.

I am keeping the problematic kernel in case anyone is interested.

Patrick.


""Patrick Bihan-Faou"" <patrick@netzuno.com> wrote in message
news:<HJEEKLMFLKEOKHOKNPBMIEHCCLAA.patrick@netzuno.com>...
> Hi,
>
>
> I am building a custom bootable CD for my own needs based on FreeBSD
> 4.x-STABLE. I am using stock FreeBSD code, and everything was working fine
> until yesterday when I update the code.
>
> The problem I am seeing is that during the boot of the CD I get a
> "elf_loadexec: cannot seek" error and the kernel does not load.
>
> I have added a trace in sys/boot/common/load_elf.c to see the values of
> local variables at the time this message is printed and here is the output
> (with my trace):
>
>
> Hit [Enter] to boot immediately, or any other key for command prompt.
> Booting [kernel]...
> /kernel text=0x1391c9 data=0x2eb4f4+0x165c0
> elf_loadexec: cannot seek
> fd=0, i=3, p_filesz=3060980, p_offset=1282528, fcopy=0, errno=94
> can't load 'kernel'
> can't load 'kernel.old'
>
> Type '?' for a list of commands, 'help' for more detailed help.
> ok
>
>
> Now the strange thing is that errno has a value that is not defined
anywhere
> and does not correspond to the "official" error codes that lseek is
supposed
> to return. For this reason I am assuming that lseek() is failing in the
> VOP_GETATTR call (cf. code snipet).
>
> Would anybody have any idea as to what could be causing this ?
>
> This code was checked out with the following tag/date: -r RELENG_4 -D
> "2001/02/27 23:00 EST"
>
>
> My last successfull build was with the following tag/date: -r RELENG_4 -D
> "2001/02/15 12:00 EST"
>
>
> The system I am using to do the builds is RELENG_4 as of mid january.
>
>
> Thanks in advance for any suggestions.
>
>
> Patrick.
>
>
>
> -------------------------------------------------------------------------
> Patch added in sys/boot/common/load_elf.c (rev 1.13.2.1):
>
> Index: load_elf.c
> ===================================================================
> RCS file: /cvs/freebsd/src/sys/boot/common/load_elf.c,v
> retrieving revision 1.13.2.1
> diff -u -r1.13.2.1 load_elf.c
> --- load_elf.c  2000/12/28 13:12:35     1.13.2.1
> +++ load_elf.c  2001/02/28 06:08:16
> @@ -268,6 +268,7 @@
>         if (phdr[i].p_filesz > fpcopy) {
>             if (lseek(fd, phdr[i].p_offset + fpcopy, SEEK_SET) == -1) {
>                 printf("\nelf_loadexec: cannot seek\n");
> +               printf("fd=%d, i=%d, p_filesz=%lu p_offset=%lu,
fpcopy=%lu,
> errno=%d\n", fd, i, phdr[i].p_filesz, phdr[i].p_offset, fpcopy, errno);
>                 goto out;
>             }
>             if (archsw.arch_readin(fd, phdr[i].p_vaddr + off + fpcopy,
>
>
>
> --------------------------------------------------------------------------
>
> lseek code from sys/kern/vfs_syscalls.c (rev 1.151.2.6):
>
> lseek(p, uap)
>     struct proc *p;
>     register struct lseek_args /* {
>         syscallarg(int) fd;
>         syscallarg(int) pad;
>         syscallarg(off_t) offset;
>         syscallarg(int) whence;
>     } */ *uap;
> {
>     struct ucred *cred = p->p_ucred;
>     register struct filedesc *fdp = p->p_fd;
>     register struct file *fp;
>     struct vattr vattr;
>     int error;
>
>     if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
>         (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
>         return (EBADF);
>     if (fp->f_type != DTYPE_VNODE)
>         return (ESPIPE);
>     switch (SCARG(uap, whence)) {
>     case L_INCR:
>         fp->f_offset += SCARG(uap, offset);
>         break;
>     case L_XTND:
>         error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p);
>         if (error)
>             return (error);
>         fp->f_offset = SCARG(uap, offset) + vattr.va_size;
>         break;
>     case L_SET:
>         fp->f_offset = SCARG(uap, offset);
>         break;
>     default:
>         return (EINVAL);
>     }
>     *(off_t *)(p->p_retval) = fp->f_offset;
>     return (0);
> }
>
>
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-stable" in the body of the message
>


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?HJEEKLMFLKEOKHOKNPBMOEJPCLAA.patrick>