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>