linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] Gujin linux.kgz boot format
@ 2005-10-06 13:39 Etienne Lorrain
  0 siblings, 0 replies; 13+ messages in thread
From: Etienne Lorrain @ 2005-10-06 13:39 UTC (permalink / raw)
  To: linux-kernel

  Sorry, it has happen again, some software removed the last newline
 of the patches during attachement.
 To rebuild them, just add a newline at end of each file:

$ wget
'http://marc.theaimsgroup.com/?l=linux-kernel&m=112859209607340&q=p3' -O
patch2614rc3-1
$ wget
'http://marc.theaimsgroup.com/?l=linux-kernel&m=112859247823724&q=p3' -O
patch2614rc3-2
$ wget
'http://marc.theaimsgroup.com/?l=linux-kernel&m=112859247807836&q=p3' -O
patch2614rc3-3
$ echo >> patch2614rc3-1
$ echo >> patch2614rc3-2
$ echo >> patch2614rc3-3
$ cd linux-2.6.14-rc3
$ patch -p1 -i ../patch2614rc3-1
$ patch -p1 -i ../patch2614rc3-2
$ patch -p1 -i ../patch2614rc3-3

 Etienne.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-11 13:56 ` Denis Vlasenko
@ 2005-10-11 15:23   ` Etienne Lorrain
  0 siblings, 0 replies; 13+ messages in thread
From: Etienne Lorrain @ 2005-10-11 15:23 UTC (permalink / raw)
  To: Denis Vlasenko; +Cc: linux-kernel

Vda wrote:
>>  This linux-*.kgz format is the "native" format of the Gujin
>> bootloader which can be found here:
>> http://gujin.org
>
> /me looking at the site
> Wow. Isn't this overdesigned by wide margin?

  Well, you will see Gujin with its video/mouse interface on the WEB,
 because there is no point in just showing the tiny interface which
 does not even detect which video mode (or serial interface) is
 available. For that just imagine two line of text, the first being
 the copyright, the second a set of point indicating the progress
 being done loading from BIOS or from DOS.

  Now if you want to tell me that it is a lot easier to write code
 using GCC compared to an assembler, well I quite agree. The source
 code size is approx the same as Grub, with a lot less files.
 It is also a lot simpler to use the BIOS than to rewrite everything
 to be able to switch to protected mode.

> Apart from shaving a few kb's from kernel image (which are discarded
> anyway after boot, IIRC), what advantages does this bring?
> Do they outweigh effort needed to maintain it?

  Don't you think autodetection of the ways to boot a PC is a nice
 feature, so that you just have _one_ rescue CDROM/floppy/pen drive
 from now on? Also you just test a new Linux distribution without
 changing your current bootloader configuration? At least, you do
 not end up having 3 or 4 Grub and two LILO configured in 6 different
 root filesystems, some of them on removeable HD...

  Moreover, there is no need to provide boot floppies to install
 distributions on PC which cannot boot CDROMs, just give a way
 to make a Gujin floppy. It will load big kernel directly from
 the CDROM ISO9660 filesystem, in /boot directory.

  Etienne.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-06  9:46 Etienne Lorrain
  2005-10-07 14:46 ` Pavel Machek
@ 2005-10-11 13:56 ` Denis Vlasenko
  2005-10-11 15:23   ` Etienne Lorrain
  1 sibling, 1 reply; 13+ messages in thread
From: Denis Vlasenko @ 2005-10-11 13:56 UTC (permalink / raw)
  To: etienne.lorrain; +Cc: linux-kernel

On Thursday 06 October 2005 12:46, Etienne Lorrain wrote:
>   Hello,
> 
>  This is following that set of patch:
> http://marc.theaimsgroup.com/?l=linux-kernel&m=112557274910448&w=4
>  to get a simpler structure of the vmlinux boot file, named like:
> /boot/linux-2.6.14.kgz
> 
>  This linux-*.kgz format is the "native" format of the Gujin
> bootloader which can be found here:
> http://gujin.org

/me looking at the site
Wow. Isn't this overdesigned by wide margin?

>  The main change of this set of patch is the rewrite of nearly all
> the ia16/ia32 assembler of Linux into a C file named "realmode.c",
> and its include "realmode.h". The mapping of the 4 Kbytes memory
> page exchanged in between real mode and protected mode is exactly
> the same, but is described in a C structure - a lot cleaner.
>  Another big change is that the GZIP compressed file produced during
> Linux compilation now contains a comment describing some important
> information: which processor this kernel has been compiled for (so
> no invalid instruction crash when running a Athlon compiled kernel
> on a Pentium - but a nice error message from the bootloader), which
> video mode the kernel support (VGA text or VESA, and which VESA)...
>
>  If you apply this set of patch, you still can use the old method
> to boot a kernel with LILO, Loadlin, Grub or SYSLINUX, and this
> patch will not modify any assembler instruction executed on this
> boot path when you use "make bzImage" or the like.
>  To produce the new format you just have to apply at least the
> first two patch and type "make /boot/linux-gujin.kgz ROOT=auto",
> or apply the 3rd patch to get root autodetection (based on the
> partition/directory of the linux*.kgz file loaded) and type
> "make /boot/linux-gujin.kgz". (also see "make help")

Apart from shaving a few kb's from kernel image (which are discarded
anyway after boot, IIRC), what advantages does this bring?
Do they outweigh effort needed to maintain it?
--
vda

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
@ 2005-10-11 13:16 Etienne Lorrain
  0 siblings, 0 replies; 13+ messages in thread
From: Etienne Lorrain @ 2005-10-11 13:16 UTC (permalink / raw)
  To: linux-kernel; +Cc: Kalin KOZHUHAROV

Kalin KOZHUHAROV wrote:
> So you are saying: "Dump GRUB and lilo, use Gujin!" ??
>
> I don't think anybody will agree with that even if it is a better
> way in some way.
> Until some level of compatibility is guaranteed with the currently
> de facto loaders, at least I cannot support this idea in any way.
> Discussing that with GRUB and lilo devs, might be an idea, but
> who knows.

  It is even worse than that, I not only said to change the
 bootloader but also to remove one of the two links produced
 during a standard "make bzImage", the one which handle the
 real mode ia32 code, in Linux/arch/i386/boot/*.

  Sometimes, to simplify, you need to remove things. As I said,
 a Linux kernel "linux.kgz" is just a compressed binary image of
 an ELF file - it no more deals with real mode, its first
 instruction is in protected mode (no virtual memory, just flat
 one, and interrupts disabled). It still contains the processor
 it is compiled for in the GZIP comment part, in text mode.

  That has advantages like that you use a clean real mode
 environment to get all the BIOS information you want, the
 first kernel assembler instruction can be located anywhere in
 memory (even at an address currently used by BIOS/DOS because
 the relocation is very late), and there is no more any limit
 to the kernel size.
 So, at the bootloader time, you can start a FreeDOS environment
 with DOS USB drivers and load your kernel at any address you want,
 or decide that you do not want to touch the BIOS environment
 and boot from a simulated floppy on a ATAPI IDE CDROM.
 If your kernel no more boots (got a HD with SMART failure lately),
 you can get an error while loading the kernel and just can boot
 a CDROM with a IDE disk RMA generator.
 When network support will be included in Gujin, because the
 processor is still in real mode, it will be able to use the
 network BIOS with its IRQ in a transparent way.

  Note that there is no more any development for LILO or the real
 mode part of the kernel, probably people no more want to deal with
 assembler software. I can't blame them, I stopped too to use
 assembler in Gujin. I can't talk to the development teams of LILO
 or the real mode part of the kernel...

 Anyway, it is technically not possible to rely on the old real
 mode interface because things are not done at the right time,
 complete backward compatibility is kept because you just describe
 what you want at the "make" time, by typing "make bzImage" or
 "make /boot/linux-2.13.kgz".

 I can't force anybody to switch to Gujin; I am just proposing a
 way to start Linux which is a lot simpler, involves a lot less
 assembler code so is a lot easier to maintain, which is working
 right now, which is quite easy to debug (with the DBG*.exe files).
 You can boot your PC with your USB FLASH disk, your CD/DVD-ROM
 or a simple disk / partition / floppy right now, there isn't
 any configuration file because everything is autodetected - at
 least anything which cannot be selected by the graphic/mouse
 interface.
http://gujin.org

  Etienne.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-10 14:31           ` Etienne Lorrain
  2005-10-10 19:21             ` Pavel Machek
@ 2005-10-10 19:35             ` Kalin KOZHUHAROV
  1 sibling, 0 replies; 13+ messages in thread
From: Kalin KOZHUHAROV @ 2005-10-10 19:35 UTC (permalink / raw)
  To: linux-kernel

Etienne Lorrain wrote:
>>>>It seems to work okay here. Now, rewriting current boot system into C
>>>>may be good goal...
>>>
>>>  At least that is a way which does not involve modifying assembler
>>> files. Slowly everybody switches to the C version which continue
>>> to evolve (i.e. removing old BIOS calls), then the tree under
>>> arch/i386/boot is removed and we can begin to rearrange the mapping
>>> of "struct linux_param".
>>
>>Will your C version work with lilo and grub?
> 
> 
>   Tricky question. In short no, it cannot.

[snip a long explaination of why this is practically impossible]

>  Sorry I cannot be compatible with them, please note that
>  Gujin is also GPL.

So you are saying: "Dump GRUB and lilo, use Gujin!" ??

I don't think anybody will agree with that even if it is a better way in some way.
Until some level of compatibility is guaranteed with the currently de facto loaders, at least I 
cannot support this idea in any way. Discussing that with GRUB and lilo devs, might be an idea, but 
who knows.

Kalin.

-- 
|[ ~~~~~~~~~~~~~~~~~~~~~~ ]|
+-> http://ThinRope.net/ <-+
|[ ______________________ ]|


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-10 14:31           ` Etienne Lorrain
@ 2005-10-10 19:21             ` Pavel Machek
  2005-10-10 19:35             ` Kalin KOZHUHAROV
  1 sibling, 0 replies; 13+ messages in thread
From: Pavel Machek @ 2005-10-10 19:21 UTC (permalink / raw)
  To: Etienne Lorrain; +Cc: linux-kernel

Hi!

> >> > may be good goal...
> >>
> >>   At least that is a way which does not involve modifying assembler
> >>  files. Slowly everybody switches to the C version which continue
> >>  to evolve (i.e. removing old BIOS calls), then the tree under
> >>  arch/i386/boot is removed and we can begin to rearrange the mapping
> >>  of "struct linux_param".
> >
> > Will your C version work with lilo and grub?
> 
>   Tricky question. In short no, it cannot.

I do not see a point, then. We have bad assembly bootup code. Adding
good C bootup code, that is incompatible with lilo/grub does nothing
to clean the mess up.
								Pavel
-- 
if you have sharp zaurus hardware you don't need... you know my address

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-10 13:19         ` Pavel Machek
@ 2005-10-10 14:31           ` Etienne Lorrain
  2005-10-10 19:21             ` Pavel Machek
  2005-10-10 19:35             ` Kalin KOZHUHAROV
  0 siblings, 2 replies; 13+ messages in thread
From: Etienne Lorrain @ 2005-10-10 14:31 UTC (permalink / raw)
  To: Pavel Machek; +Cc: linux-kernel

>> > It seems to work okay here. Now, rewriting current boot system into C
>> > may be good goal...
>>
>>   At least that is a way which does not involve modifying assembler
>>  files. Slowly everybody switches to the C version which continue
>>  to evolve (i.e. removing old BIOS calls), then the tree under
>>  arch/i386/boot is removed and we can begin to rearrange the mapping
>>  of "struct linux_param".
>
> Will your C version work with lilo and grub?

  Tricky question. In short no, it cannot.

 It is in fact theoretically possible to boot the same way for LILO,
 Grub and SYSLINUX to still work, and then call this linux_set_params()
 function but involves a lot of assembler programming and linker setup.
 I have done this exact work once with Gujin, but then I was in full
 control of the bootloader, in a setup which was already in C, has the
 stack setup, where I can free the first 4 Kbytes of data (located at
 address 0) for use by this kernel function. It was far to be simple.

 One of the problem I can see is that you currently have two link
 being done by the linker, one in real mode and one in protected mode.
 You cannot have cross references in between those two links, and for
 instance with Gujin, you are filling the content of the LnxParam
 pointer, which is transparently copied at its right position before
 jumping to the Linux kernel code. You will need a seriously more
 complex linker file to forbid cross references, and duplicate Gujin
 treatment about memory setup (in this case that may involve HIMEM/EMM
 primitive calling if starting under DOS).

 Note that if this kernel function returns an error, Gujin will
 display an error message and you can select another kernel to boot,
 but you cannot return to LILO or Grub with an error...

 Modifying the bootloader may be possible, but lately I had another
 look at LILO source and I do not want to touch it.  If you run Grub,
 you loose the "BIOS information gathering before switching to
 protected mode" advantage, BIOS environment may still be broken.
 SYSLINUX is probably at lot more accessible, and Gujin still do
 not support network booting (It can be added, but my TODO list is
 long), but you will want to call a function which is curently at
 the end of a still compressed image.

 Sorry I cannot be compatible with them, please note that
 Gujin is also GPL.
 Etienne.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-10 13:09       ` Etienne Lorrain
@ 2005-10-10 13:19         ` Pavel Machek
  2005-10-10 14:31           ` Etienne Lorrain
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Machek @ 2005-10-10 13:19 UTC (permalink / raw)
  To: Etienne Lorrain; +Cc: linux-kernel

Hi!

> > It seems to work okay here. Now, rewriting current boot system into C
> > may be good goal...
> 
>   At least that is a way which does not involve modifying assembler
>  files. Slowly everybody switches to the C version which continue
>  to evolve (i.e. removing old BIOS calls), then the tree under
>  arch/i386/boot is removed and we can begin to rearrange the mapping
>  of "struct linux_param".

Will your C version work with lilo and grub?
								Pavel

-- 
Boycott Kodak -- for their patent abuse against Java.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-10 11:56     ` Pavel Machek
@ 2005-10-10 13:09       ` Etienne Lorrain
  2005-10-10 13:19         ` Pavel Machek
  0 siblings, 1 reply; 13+ messages in thread
From: Etienne Lorrain @ 2005-10-10 13:09 UTC (permalink / raw)
  To: Pavel Machek; +Cc: linux-kernel

> It seems to work okay here. Now, rewriting current boot system into C
> may be good goal...

  At least that is a way which does not involve modifying assembler
 files. Slowly everybody switches to the C version which continue
 to evolve (i.e. removing old BIOS calls), then the tree under
 arch/i386/boot is removed and we can begin to rearrange the mapping
 of "struct linux_param".

>>  I seriously doubt you can even imagine an AMD 64 bits with an ISA
>>  trident 8900 video card inside, even for fun: you cannot plug it
>>  in.
>
> Feel free to fix that. [I think I could get PCI-to-ISA bridge and plug
> it into my x86-64 box...]

  Well, I can help to plug it in, but it involves a set of tool not
 usually used in computer software, that is hammer and axes :-)
 For the software support of VESA 1 bank switching to display graphic
 modes in 64 Kbytes memory window, well, Gujin support it but not Linux.
 For my future investment in a x86-64, well I will one day, it is on
 my TODO list. I wonder about PCI-E -> ISA converter, they should be
 faster than PCI -> ISA, no?...

>>   Well, you want to comment on the only file which is a standalone
>>  application and not released under GPL but BSD license, because it
>>  may be usefull elsewhere.
>
> Well, if you want to distribute the file with kernel, it should
> folllow kernel coding style. If not, sorry for the noise.

  I hope I can still put a BSD license "helper" in kernel tree, it
 is BSD because GZIP is itself BSD licensed - and its indentation
 looks like GZIP source.

>> >> +#ifndef CONFIG_FB_VESA
>> >> +	| (1 << 0)	/* Cannot boot in MASKVESA_1BPP */
>> >> +	| (1 << 1)	/* Cannot boot in MASKVESA_2BPP */
>> >> +	| (1 << 3)	/* Cannot boot in MASKVESA_4BPP */
>> >> +	| (1 << 7)	/* Cannot boot in MASKVESA_8BPP */
>> >> +	| (1 << 14)	/* Cannot boot in MASKVESA_15BPP */
>> >> +	| (1 << 15)	/* Cannot boot in MASKVESA_16BPP */
>> >> +	| (1 << 23)	/* Cannot boot in MASKVESA_24BPP */
>> >> +	| (1 << 31)	/* Cannot boot in MASKVESA_32BPP */
>> >> +#endif
>> >> +#if defined (CONFIG_VGA_CONSOLE) || defined (CONFIG_MDA_CONSOLE)
>> >> +	| (1 << 16)	/* able to boot in text mode */
>> >> +#endif
>> >> +	// | (1 << 17)	/* not able to boot in VESA1 mode */
>> >> +#ifdef CONFIG_FB_VESA
>> >> +	| (1 << 18)	/* able to boot in VESA2 linear mode */
>> >> +#endif
>> >> +	// | (1 << 19)	/* force VESA1 if in VESA2 */
>> >> +	| (1 << 20)	/* Cannot handle VGA graphic modes */
>> >> +	;
>>
>>   No comment here. Well I know the use of ifdef's is deprecated, but
>>  there is simply no other way here - and lets face it: recompiling
>>  a 10 lines C function (with the host compiler and not the target one
>>  when cross compiling) at each kernel configuration change is not that
>>  long.
>
> // comments are deprecated, too, and you probably should use symbolic
> constant, no?

  For the "//" comment I have to check those patches; I am used to put
 them when the user may think of changing it for configuration.

  I do not want to use symbolic constant, as in:
static const unsigned MASKVESA_1BPP = 1 << 0;
  because the assembler generated is bad (a real area of memory is
 reserved - it is constant in C but may be modified in assembler).
 I do not put my constant as enum because I am still not a real
 C++ software writer (don't tell my boss!).

  I could do:
#define MASKVESA_1BPP	(1 << 0)
  as in Gujin vmlinuz.h, but because it is used once and only once,
 I did put MASKVESA_1BPP as comment (use one source line instead
 of two). I can change it, I have enough spare "linefeed" -:)

  My bigger problem was for the CPUID detection, I did not know if
 I should use Gujin library.h structure:
struct cpuid_flags_str {
    unsigned	fpu	: 1;
    unsigned	vme	: 1;
    unsigned	de	: 1;
    unsigned	pse	: 1;
    unsigned	tsc	: 1;
    unsigned	msr	: 1;
    unsigned	pae	: 1;
    unsigned	mce	: 1;
    unsigned	cx8	: 1;
    unsigned	apic	: 1;
    unsigned	unused3	: 1;
    unsigned	sep	: 1;
    unsigned	mtrr	: 1;
    unsigned	pge	: 1;
    unsigned	mca	: 1;
    unsigned	cmov	: 1;
    unsigned	pat	: 1;
    unsigned	pse36	: 1;
    unsigned	psn	: 1;
    unsigned	clfl	: 1;
    unsigned	unused2	: 1;
    unsigned	dtes	: 1;
    unsigned	acpi	: 1;
    unsigned	mmx	: 1;
    unsigned	fxsr	: 1;
    unsigned	sse	: 1;
    unsigned	sse2	: 1;
    unsigned	ss	: 1;
    unsigned	htt	: 1;
    unsigned	tm	: 1;
    unsigned	ia64	: 1;
    unsigned	unused1	: 1;

    unsigned	mapping_to_define;
    } __attribute__ ((packed));

  and:
struct cpuid_amd_flags_str {
    unsigned	fpu	: 1;
    unsigned	vme	: 1;
    unsigned	de	: 1;
    unsigned	pse	: 1;
    unsigned	tsc	: 1;
    unsigned	msr	: 1;
    unsigned	pae	: 1;
    unsigned	mce	: 1;
    unsigned	cx8	: 1;
    unsigned	apic	: 1;
    unsigned	unused3	: 1;
    unsigned	sep	: 1;
    unsigned	mtrr	: 1;
    unsigned	pge	: 1;
    unsigned	mca	: 1;
    unsigned	cmov	: 1;
    unsigned	pat	: 1; /* or FCMOV */
    unsigned	pse36	: 1;
    unsigned	unused2	: 4;
    unsigned	mmxplus	: 1;
    unsigned	mmx	: 1;
    unsigned	fxsr	: 1; /* or emmx, Cyrix */
    unsigned	unused1	: 4;
    unsigned	lm	: 1;
    unsigned	E3Dnow	: 1; /* Extended 3DNow!+ */
    unsigned	S3Dnow	: 1; /* Standard 3DNow! */
    } __attribute__ ((packed));

  and because of the complexity decided to build the constant
 manually, which led to manual building of the video constant.

  Somebody else would like some other modifications?

  Cheers,
  Etienne.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-10 11:23   ` Etienne Lorrain
@ 2005-10-10 11:56     ` Pavel Machek
  2005-10-10 13:09       ` Etienne Lorrain
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Machek @ 2005-10-10 11:56 UTC (permalink / raw)
  To: Etienne Lorrain; +Cc: linux-kernel

Hi!

> >>  It perfectly works for me, and even after reading those tens of times
> >> I no more find anything to change or improve.
> >>  Can someone propose a way forward, either in the direction of
> >> linux-2.6.14/15 or in the -mm tree, and/or propose improvement or
> >> point me to my bug(s) ?
> >
> > And advantages are? Having to maintain both C and assembly version
> > does not seem like improvement to me.
> 
>   The problem is that you call the assembly version "maintained".
>  When I started hacking that part, in 1998, I tried to rewrite it

It seems to work okay here. Now, rewriting current boot system into C
may be good goal...

>  I am not alone to not want to touch those assembler files: If you
>  have a look at Linux/arch/x86_64/boot/video.S you will see that
>  on an X86_64 architecture, people are doing I/O port and PCI
>  peek/poke all over the place to detect video cards which have
>  only been available on ISA bus, two bus generation ago!
>  I seriously doubt you can even imagine an AMD 64 bits with an ISA
>  trident 8900 video card inside, even for fun: you cannot plug it
>  in.

Feel free to fix that. [I think I could get PCI-to-ISA bridge and plug
it into my x86-64 box...]

> >> +#define STR static const char
> >
> > Ouch.
> 
>   Well, you want to comment on the only file which is a standalone
>  application and not released under GPL but BSD license, because it
>  may be usefull elsewhere.

Well, if you want to distribute the file with kernel, it should
folllow kernel coding style. If not, sorry for the noise.

>  The fact that it is released on a BSD license (if a collection
>  of GZIP utilities is ever built) also changes the indentation
>  rules if that matter.

License does not say anything about coding style. 

> >  +const unsigned maskvesa = 0
> >
> >> +#ifndef CONFIG_FB_VESA
> >> +	| (1 << 0)	/* Cannot boot in MASKVESA_1BPP */
> >> +	| (1 << 1)	/* Cannot boot in MASKVESA_2BPP */
> >> +	| (1 << 3)	/* Cannot boot in MASKVESA_4BPP */
> >> +	| (1 << 7)	/* Cannot boot in MASKVESA_8BPP */
> >> +	| (1 << 14)	/* Cannot boot in MASKVESA_15BPP */
> >> +	| (1 << 15)	/* Cannot boot in MASKVESA_16BPP */
> >> +	| (1 << 23)	/* Cannot boot in MASKVESA_24BPP */
> >> +	| (1 << 31)	/* Cannot boot in MASKVESA_32BPP */
> >> +#endif
> >> +#if defined (CONFIG_VGA_CONSOLE) || defined (CONFIG_MDA_CONSOLE)
> >> +	| (1 << 16)	/* able to boot in text mode */
> >> +#endif
> >> +	// | (1 << 17)	/* not able to boot in VESA1 mode */
> >> +#ifdef CONFIG_FB_VESA
> >> +	| (1 << 18)	/* able to boot in VESA2 linear mode */
> >> +#endif
> >> +	// | (1 << 19)	/* force VESA1 if in VESA2 */
> >> +	| (1 << 20)	/* Cannot handle VGA graphic modes */
> >> +	;
> 
>   No comment here. Well I know the use of ifdef's is deprecated, but
>  there is simply no other way here - and lets face it: recompiling
>  a 10 lines C function (with the host compiler and not the target one
>  when cross compiling) at each kernel configuration change is not that
>  long.

// comments are deprecated, too, and you probably should use symbolic
constant, no?

> > if you have sharp zaurus hardware you don't need... you know my address
> 
>   Sorry I do not... fun but not enough storage space.

Takes CF cards just fun. You can get 1GB CF cards these days, and
microdrives are even bigger.
								Pavel
-- 
if you have sharp zaurus hardware you don't need... you know my address

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-07 14:46 ` Pavel Machek
@ 2005-10-10 11:23   ` Etienne Lorrain
  2005-10-10 11:56     ` Pavel Machek
  0 siblings, 1 reply; 13+ messages in thread
From: Etienne Lorrain @ 2005-10-10 11:23 UTC (permalink / raw)
  To: Pavel Machek; +Cc: linux-kernel

  Hello, and thanks for reading my patch,

>>  It perfectly works for me, and even after reading those tens of times
>> I no more find anything to change or improve.
>>  Can someone propose a way forward, either in the direction of
>> linux-2.6.14/15 or in the -mm tree, and/or propose improvement or
>> point me to my bug(s) ?
>
> And advantages are? Having to maintain both C and assembly version
> does not seem like improvement to me.

  The problem is that you call the assembly version "maintained".
 When I started hacking that part, in 1998, I tried to rewrite it
 cleanly and fix obvious bugs - but assembler is not the right tool
 for this job and touching those assembler files would break some
 configuration - even if some other configuration would work better.

 I am not alone to not want to touch those assembler files: If you
 have a look at Linux/arch/x86_64/boot/video.S you will see that
 on an X86_64 architecture, people are doing I/O port and PCI
 peek/poke all over the place to detect video cards which have
 only been available on ISA bus, two bus generation ago!
 I seriously doubt you can even imagine an AMD 64 bits with an ISA
 trident 8900 video card inside, even for fun: you cannot plug it in.

 The problem of assembler is that when it has been put in, you cannot
 remove anything because at the time you want to remove old stuff,
 you no more understand the implications. You can not, like in C,
 stop calling a function and hope everything will be right. With my
 code, when you will want to get rid of the APM stuff, you just
 remove the function call vmlinuz_APM() and recompile.

 I am, with this set of patch, proposing a new way to boot. This
 way enable you to boot unlimited size kernel ("make allyesconfig"
 produces a bootable linux.kgz kernel) and the BIOS information
 collection is done in C while in real mode. This real mode function
 can be a lot bigger than it is currently, so that you can temporarily
 call some printf() equivalent while collecting data - instead of
 trying to get a clue of what has happen *after* the crash.

 There is no extended time spent in protected mode (unlike Grub)
 before collecting BIOS information, so that the BIOS environment
 has not been broken (for instance older BIOS APM power saving system
 would be active at startup on some PC, setting timer interrupt to
 slowly reduce power consumption in real mode. Grub switching to
 protected mode stop serving those interrupts, and may not work on
 this PC, or the BIOS information may be invalid).

>> +#define STR static const char
>
> Ouch.

  Well, you want to comment on the only file which is a standalone
 application and not released under GPL but BSD license, because it
 may be usefull elsewhere.

 I have written:
#define STR static const char
 then 50 strings, then
#undef STR

  The main advantage is that it saves screen space, when you want to
 group all the messages together because this standalone utility may
 be translated to other languages, unlike the kernel itself.
 The way to support other languages in C can be complex, and all
 those string can also be wchar_t, or an array of array of chars,
 and the "static" keyword may or may not be a good idea.
 The fact that it is released on a BSD license (if a collection
 of GZIP utilities is ever built) also changes the indentation
 rules if that matter.
  I am not sure we want to talk a lot about this file, it is just
 a simple executable to edit a string at a fixed position inside
 an otherwise binary file (as GZIP specifications), it can be
 written in a lot of other languages, or with shell commands
 like "cut" and file concatenation - it is just cleaner this way.


> 								Pavel
>  +const unsigned maskvesa = 0
>
>> +#ifndef CONFIG_FB_VESA
>> +	| (1 << 0)	/* Cannot boot in MASKVESA_1BPP */
>> +	| (1 << 1)	/* Cannot boot in MASKVESA_2BPP */
>> +	| (1 << 3)	/* Cannot boot in MASKVESA_4BPP */
>> +	| (1 << 7)	/* Cannot boot in MASKVESA_8BPP */
>> +	| (1 << 14)	/* Cannot boot in MASKVESA_15BPP */
>> +	| (1 << 15)	/* Cannot boot in MASKVESA_16BPP */
>> +	| (1 << 23)	/* Cannot boot in MASKVESA_24BPP */
>> +	| (1 << 31)	/* Cannot boot in MASKVESA_32BPP */
>> +#endif
>> +#if defined (CONFIG_VGA_CONSOLE) || defined (CONFIG_MDA_CONSOLE)
>> +	| (1 << 16)	/* able to boot in text mode */
>> +#endif
>> +	// | (1 << 17)	/* not able to boot in VESA1 mode */
>> +#ifdef CONFIG_FB_VESA
>> +	| (1 << 18)	/* able to boot in VESA2 linear mode */
>> +#endif
>> +	// | (1 << 19)	/* force VESA1 if in VESA2 */
>> +	| (1 << 20)	/* Cannot handle VGA graphic modes */
>> +	;

  No comment here. Well I know the use of ifdef's is deprecated, but
 there is simply no other way here - and lets face it: recompiling
 a 10 lines C function (with the host compiler and not the target one
 when cross compiling) at each kernel configuration change is not that
 long.
  Note that if you try to start with LILO a kernel in VESA graphic
 mode and the kernel is not compiled with CONFIG_FB_VESA, well, no
 error message is displayed because the kernel do not know how
 to display stuff... With Gujin you cannot start this kernel and
 you get a clear error message.
 You can also try to start a kernel in 320x200 4 colors modes...

--
> if you have sharp zaurus hardware you don't need... you know my address

  Sorry I do not... fun but not enough storage space.

  Cheers,
  Etienne.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Gujin linux.kgz boot format
  2005-10-06  9:46 Etienne Lorrain
@ 2005-10-07 14:46 ` Pavel Machek
  2005-10-10 11:23   ` Etienne Lorrain
  2005-10-11 13:56 ` Denis Vlasenko
  1 sibling, 1 reply; 13+ messages in thread
From: Pavel Machek @ 2005-10-07 14:46 UTC (permalink / raw)
  To: Etienne Lorrain; +Cc: linux-kernel

Hi!

>  It perfectly works for me, and even after reading those tens of times
> I no more find anything to change or improve.
>  Can someone propose a way forward, either in the direction of
> linux-2.6.14/15 or in the -mm tree, and/or propose improvement or
> point me to my bug(s) ?

And advantages are? Having to maintain both C and assembly version
does not seem like improvement to me.

> +#define STR static const char

Ouch.
								Pavel
 +const unsigned maskvesa = 0

> +#ifndef CONFIG_FB_VESA
> +	| (1 << 0)	/* Cannot boot in MASKVESA_1BPP */
> +	| (1 << 1)	/* Cannot boot in MASKVESA_2BPP */
> +	| (1 << 3)	/* Cannot boot in MASKVESA_4BPP */
> +	| (1 << 7)	/* Cannot boot in MASKVESA_8BPP */
> +	| (1 << 14)	/* Cannot boot in MASKVESA_15BPP */
> +	| (1 << 15)	/* Cannot boot in MASKVESA_16BPP */
> +	| (1 << 23)	/* Cannot boot in MASKVESA_24BPP */
> +	| (1 << 31)	/* Cannot boot in MASKVESA_32BPP */
> +#endif
> +#if defined (CONFIG_VGA_CONSOLE) || defined (CONFIG_MDA_CONSOLE)
> +	| (1 << 16)	/* able to boot in text mode */
> +#endif
> +	// | (1 << 17)	/* not able to boot in VESA1 mode */
> +#ifdef CONFIG_FB_VESA
> +	| (1 << 18)	/* able to boot in VESA2 linear mode */
> +#endif
> +	// | (1 << 19)	/* force VESA1 if in VESA2 */
> +	| (1 << 20)	/* Cannot handle VGA graphic modes */
> +	;


-- 
if you have sharp zaurus hardware you don't need... you know my address

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/3] Gujin linux.kgz boot format
@ 2005-10-06  9:46 Etienne Lorrain
  2005-10-07 14:46 ` Pavel Machek
  2005-10-11 13:56 ` Denis Vlasenko
  0 siblings, 2 replies; 13+ messages in thread
From: Etienne Lorrain @ 2005-10-06  9:46 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2405 bytes --]

  Hello,

 This is following that set of patch:
http://marc.theaimsgroup.com/?l=linux-kernel&m=112557274910448&w=4
 to get a simpler structure of the vmlinux boot file, named like:
/boot/linux-2.6.14.kgz

 This linux-*.kgz format is the "native" format of the Gujin
bootloader which can be found here:
http://gujin.org
 The main change of this set of patch is the rewrite of nearly all
the ia16/ia32 assembler of Linux into a C file named "realmode.c",
and its include "realmode.h". The mapping of the 4 Kbytes memory
page exchanged in between real mode and protected mode is exactly
the same, but is described in a C structure - a lot cleaner.
 Another big change is that the GZIP compressed file produced during
Linux compilation now contains a comment describing some important
information: which processor this kernel has been compiled for (so
no invalid instruction crash when running a Athlon compiled kernel
on a Pentium - but a nice error message from the bootloader), which
video mode the kernel support (VGA text or VESA, and which VESA)...

 If you apply this set of patch, you still can use the old method
to boot a kernel with LILO, Loadlin, Grub or SYSLINUX, and this
patch will not modify any assembler instruction executed on this
boot path when you use "make bzImage" or the like.
 To produce the new format you just have to apply at least the
first two patch and type "make /boot/linux-gujin.kgz ROOT=auto",
or apply the 3rd patch to get root autodetection (based on the
partition/directory of the linux*.kgz file loaded) and type
"make /boot/linux-gujin.kgz". (also see "make help")

 This set has few changes: applies on all distributions (end-of-line
at end-of-file problem on Fedora3), updated to apply on 2.6.13-rc3 -
or 2.6.13.rc2-mm2 with few offsets, compiles also without warnings
on GCC-2.95.3 and GCC-4.0.*, links without problem (no more
memcpy()/memset() called).

 It perfectly works for me, and even after reading those tens of times
I no more find anything to change or improve.
 Can someone propose a way forward, either in the direction of
linux-2.6.14/15 or in the -mm tree, and/or propose improvement or
point me to my bug(s) ?

  Attached first patch just add two standalone executable, one
to manage GZIP comments, the other to display a text line of the
parameters used to compile the kernel.

Signed-off-by: Etienne Lorrain <etienne_lorrain@gujin.org>

  Etienne.

[-- Attachment #2: patch2614rc3-1 --]
[-- Type: text/plain, Size: 41042 bytes --]

diff -uprN -X linux-2.6.14-rc3/Documentation/dontdiff -x '*.orig' -x '*.cmd' -x '.tmp*' -x '*.o' -x '*.ko' -x '*.a' -x '*.so' -x '.config*' -x asm-offsets.s -x asm_offsets.h -x vmlinux.lds -x vsyscall.lds -x '*.mod.c' -x Module.symvers -x consolemap_deftbl.c -x defkeymap.c -x classlist.h -x devlist.h -x asm -x md -x scsi -x logo -x config -x .version -x zconf.tab.h -x elfconfig.h -x System.map -x zconf.tab.c -x lex.zconf.c -x compile.h -x config_data.h -x version.h -x crc32table.h -x autoconf.h -x gen-devlist -x initramfs_list linux-2.6.14-rc3/Makefile linux-2.6.14-rc3-1/Makefile
--- linux-2.6.14-rc3/Makefile	2005-09-30 23:17:35.000000000 +0200
+++ linux-2.6.14-rc3-1/Makefile	2005-10-04 15:45:27.120598944 +0200
@@ -766,6 +766,19 @@ vmlinux: $(vmlinux-lds) $(vmlinux-init) 
 	$(call if_changed_rule,vmlinux__)
 	$(Q)rm -f .old_version
 
+# Utility to display the kernel compile time parameters
+quiet_cmd_gzparam = HOSTCC  $@
+      cmd_gzparam = $(HOSTCC) $(HOSTCFLAGS) -Wl,"-u __ERROR" -o $@ $<
+      # Need to rebuild this if "include/linux/autoconf.h" changed:
+scripts/gzparam: scripts/gzparam.c vmlinux FORCE
+	$(call cmd,gzparam)
+
+# Maybe move building this utility somewhere else?
+quiet_cmd_gzcopy = HOSTCC  $@
+      cmd_gzcopy = $(HOSTCC) $(HOSTCFLAGS) -s -o $@ $<
+scripts/gzcopy: scripts/gzcopy.c
+	$(call cmd,gzcopy)
+
 # The actual objects are generated when descending, 
 # make sure no implicit rule kicks in
 $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
@@ -978,6 +991,7 @@ endif # CONFIG_MODULES
 # Directories & files removed with 'make clean'
 CLEAN_DIRS  += $(MODVERDIR)
 CLEAN_FILES +=	vmlinux System.map \
+                scripts/gzparam scripts/gzcopy \
                 .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
 
 # Directories & files removed with 'make mrproper'
diff -uprN -X linux-2.6.14-rc3/Documentation/dontdiff -x '*.orig' -x '*.cmd' -x '.tmp*' -x '*.o' -x '*.ko' -x '*.a' -x '*.so' -x '.config*' -x asm-offsets.s -x asm_offsets.h -x vmlinux.lds -x vsyscall.lds -x '*.mod.c' -x Module.symvers -x consolemap_deftbl.c -x defkeymap.c -x classlist.h -x devlist.h -x asm -x md -x scsi -x logo -x config -x .version -x zconf.tab.h -x elfconfig.h -x System.map -x zconf.tab.c -x lex.zconf.c -x compile.h -x config_data.h -x version.h -x crc32table.h -x autoconf.h -x gen-devlist -x initramfs_list linux-2.6.14-rc3/scripts/gzcopy.c linux-2.6.14-rc3-1/scripts/gzcopy.c
--- linux-2.6.14-rc3/scripts/gzcopy.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14-rc3-1/scripts/gzcopy.c	2005-10-04 15:45:27.102601680 +0200
@@ -0,0 +1,1006 @@
+/*
+ * gzcopy: utility to copy (only) GZip files, possibly displaying or
+ * modifying their header.
+ *
+ * Copyright (C) 2004 Etienne Lorrain, fingerprint (2D3AF3EA):
+ *   2471 DF64 9DEE 41D4 C8DB 9667 E448 FF8C 2D3A F3EA
+ * E-Mail: etienne dot lorrain at gujin dot org
+ *
+ *   This software is provided 'as-is', without any express or implied
+ *  warranty.  In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, subject to the following restrictions:
+ *
+ *  1. The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  2. Altered source versions must be plainly marked as such, and must not be
+ *     misrepresented as being the original software.
+ *  3. This notice may not be removed or altered from any source distribution.
+ *
+ *   The data format used by the zlib library is described by RFCs (Request for
+ *  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ *  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+ */
+
+/*
+ * TODO: Manage (extract/remove/insert...) concatenated ZIP files.
+ *
+ * Changelog:
+ * 15/9/2001: Etienne Lorrain. Initial release for the Gujin bootloader.
+ * 23/8/2002: Etienne Lorrain. '-s' -> '-c', only one input/output file
+ * 10/9/2004: Etienne Lorrain. Formal BSD-like license release & correct minibug.
+ * 28/9/2005: Etienne Lorrain. remove warning line 838: [unsigned] char *ptr = full_content;
+ *
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <errno.h>
+#include <sys/stat.h>		/* stat() */
+#include <unistd.h>		/* stat() */
+
+#if 0
+#include <string.h>
+#else
+static inline unsigned strlen(const char *str)
+{
+	const char *ptr = str;
+	while (*ptr)
+		ptr++;
+	return ptr - str;
+}
+
+static inline void my_strcpy(char *dst, const char *src)
+{
+	while (*src)
+		*dst++ = *src++;
+	*dst = *src;		/* copy the zero */
+}
+#define strcpy my_strcpy
+
+static inline void my_strcat(char *dst, const char *src)
+{
+	dst += strlen(dst);
+	strcpy(dst, src);
+}
+#define strcat my_strcat
+
+static inline unsigned strcmp(const char *s1, const char *s2)
+{
+	while (*s1 && *s1 == *s2) {
+		s1++;
+		s2++;
+	}
+	return (*s1 != *s2);
+}
+#endif
+
+#define STR static const char
+
+STR usage[] = "gzcopy: utility to copy (only) GZip files, possibly displaying\n"
+	      "        or modifying their header.\n"
+    "Copyright 2003 Etienne Lorrain, BSD-like license.\n"
+    "USAGE:\n"
+    "    gzcopy -h              -> display this help\n"
+    "    gzcopy -V              -> display the version\n"
+    "    gzcopy -v              -> be verbose\n"
+    "    gzcopy -c infile.gz    -> show the comment. (-c0 for raw form)\n"	/* was -s */
+    "    gzcopy -c='' infile.gz outfile.gz    -> set (clear if '') the comment\n"
+    "    gzcopy -a=\"<a comment>\" in.gz out.gz -> add/append a comment\n"
+    "    gzcopy -p='<a comment>' in.gz out.gz -> add/prepend a comment.\n"
+    "    gzcopy -k infile.gz    -> show the header CRC. (-k0 for raw form)\n"
+    "    gzcopy -k={0,1} infile.gz outfile.gz  -> (de)activate the header CRC\n"
+    "    gzcopy -b infile.gz    -> show the text/binary flag\n"
+    "    gzcopy -b={0,1} infile.gz outfile.gz  -> set the flag: binary=0/text=1\n"
+    "    gzcopy -n infile.gz    -> show the original name. (-n0 for raw form)\n"
+    "    gzcopy -n=filename in.gz out.gz       -> set (clear if '') original name\n"
+    "NOTE:\n"
+    " Use multiple command: gzcopy -c= -a='com' -a='m' -pl='ent' in.gz out.gz .\n"
+    " Use option -a{s,l,t} or -p{s,l,t} to check/force a {space,linefeed,tab}\n"
+    "  in between comment parts. Use filename \"-\" for stdin and/or stdout.\n"
+    " Use the -f option to force overwriting output file, or if you want\n"
+    " the output in the input file - you then need a lot of virtual memory.\n";
+
+STR version[] = "gzcopy version 1.2 (C) 2003 Etienne Lorrain, BSD-like license.";
+STR show_textflags_text_msg[] = "\"%s\" is probably a text file\n";
+STR show_textflags_binary_msg[] = "\"%s\" is probably a binary file\n";
+STR show_header_crc_msg[] = "\"%s\" header CRC16 is 0x%X.\n";
+STR no_CRC_to_show_msg[] = "\"%s\" does not contain any header CRC.\n";
+STR show_name_msg[] = "\"%s\" original name: \"%s\"\n";
+STR no_name_to_show_msg[] = "\"%s\" does not contain any original name.\n";
+STR show_comment_msg[] = "\"%s\" comment: \"%s\"\n";
+STR no_comment_to_show_msg[] = "\"%s\" does not contain any comment.\n";
+
+#define PRINTERR(format, args...) do { \
+	if (errno) perror ("gzcopy");		\
+	fprintf (stderr, "gzcopy: ");		\
+	fprintf (stderr, format , ## args);	\
+	fprintf (stderr, "\n");			\
+	} while (0)
+
+#define ENDHLP	", try: gzcopy -h"
+
+STR unknown_action[] = "unrecognised option -%c" ENDHLP;
+STR malformed_crc_param[] = "header crc option is neither "
+				"enable (-k=1) nor disable (-k=0)" ENDHLP;
+STR malformed_param[] = "no parameter after -%c= option" ENDHLP;
+STR too_many_param[] = "too many parameters: \"%s\"" ENDHLP;
+STR unknown_comment[] = "no comment to pre/append" ENDHLP;
+STR no_input_file[] = "no input file" ENDHLP;
+STR no_output_file[] = "no output file" ENDHLP;
+STR cannot_open_input_file[] = "cannot open input file \"%s\".";
+STR not_gzip_file[] = "input file \"%s\" is not a gzip file, "
+			"signature: 0x%X.";
+STR bad_header_crc[] = "bad header crc32: is 0x%X, " "should be 0x%X.";
+STR not_enough_memory[] = "not enough memory.";
+STR cannot_open_output_file[] = "cannot open input file \"%s\".";
+STR outfile_already_exists[] = "output file \"%s\" already exists and "
+				"option -f not specified.\n";
+STR cannot_write_to_file[] = "cannot write to file \"%s\".";
+STR read_input_file_error[] = "error reading from file \"%s\".";
+STR cannot_close_input_file[] = "cannot close input file \"%s\".";
+STR cannot_close_output_file[] = "cannot close output file \"%s\".";
+
+#define VERBOSE(format, args...) do { \
+	if (verbose)				\
+	    fprintf (stderr, format , ## args);	\
+	} while (0)
+
+STR treating_intput_file[] = "treating \"%s\" as input file.\n";
+STR standart_input[] = "standart input";
+STR standart_output[] = "standart output";
+STR extra_field_present[] = "extra field of %u bytes present.\n";
+STR original_name[] = "original name: \"%s\".\n";
+STR comment_present[] = "comment: \"%s\".\n";
+STR header_crc_present[] = "header CRC16 present: 0x%X.\n";
+STR treating_output_file[] = "treating \"%s\" as output file.\n";
+STR enabling_header_crc[] = "enabling header CRC.\n";
+STR disabling_header_crc[] = "disabling header CRC.\n";
+STR removing_comment[] = "removing comment.\n";
+STR replacing_comment[] = "replacing comment with \"%s\".\n";
+STR adding_comment[] = "adding comment \"%s\".\n";
+STR appending_comment[] = "appending comment \"%s\".\n";
+STR prepending_comment[] = "prepending comment \"%s\".\n";
+STR new_header_crc[] = "new header CRC16: 0x%X.\n";
+STR removing_name[] = "removing the original name field.\n";
+STR changing_name[] = "changing the original name field to \"%s\".\n";
+STR set_probablytext_flag[] = "set the probably ASCII/text flags.\n";
+STR clear_probablytext_flag[] = "clear the probably ASCII/text flags.\n";
+
+#undef STR
+
+enum main_returned_enum {
+	warn_empty_comment = 1,
+	warn_no_comment = 2,
+	err_none = 0,
+	err_too_many_param = -1,
+	err_unknown_comment = -2,
+	err_unknown_action = -3,
+	err_malformed_param = -4,
+	err_malformed_crc_param = -5,
+	err_no_input_file = -6,
+	err_no_output_file = -7,
+	err_cannot_open_input_file = -8,
+	err_not_gzip_file = -9,
+	err_bad_header_crc = -10,
+	err_not_enough_memory = -11,
+	err_cannot_open_output_file = -12,
+	err_outfile_already_exists = -13,
+	err_cannot_write_to_file = -14,
+	err_read_input_file_error = -15,
+	err_cannot_close_input_file = -16,
+	err_cannot_close_output_file = -17
+};
+
+/* The Gzip header (with unsigned char flags): */
+struct gzheader_str {
+	unsigned short signature_0x8B1F;
+	unsigned char compression_method;	/* =Z_DEFLATED */
+	unsigned char flags;
+#define FLAGS_ascii		0x01	/* file probably ascii text */
+#define FLAGS_header_crc	0x02	/* header CRC present */
+#define FLAGS_extra_field	0x04	/* extra field present */
+#define FLAGS_orig_name		0x08	/* original file name present */
+#define FLAGS_comment		0x10	/* file comment present */
+#define FLAGS_unknown		0xE0	/* reserved */
+	unsigned modif_time;	/* nb second since 1/1/1970 */
+	unsigned char extraflags;
+#define EXTRAFLAGS_max_compress	2
+#define EXTRAFLAGS_fast_algo	4
+	unsigned char operating_system;
+} __attribute__ ((packed));
+
+/* The only compression method recognised by Gzip: */
+#define Z_DEFLATED	8
+
+static inline unsigned crc32(unsigned crc, const unsigned char *buf, unsigned len)
+{
+	const unsigned char *end = buf + len;
+
+	if (buf == 0)
+		return 0L;
+
+	crc = ~crc;
+	while (buf < end) {
+		unsigned c = (crc ^ *buf++) & 0xff;
+		unsigned short k;
+#define POLY	0xedb88320L	/* polynomial exclusive-or pattern */
+		for (k = 8; k != 0; k--)
+			c = c & 1 ? (c >> 1) ^ POLY : c >> 1;
+		crc = c ^ (crc >> 8);
+	}
+	return ~crc;
+}
+
+static unsigned initheader_crc32(struct gzheader_str *hdr)
+{
+	unsigned crc = crc32(0, 0, 0);
+	return crc32(crc, (unsigned char *)hdr, sizeof(struct gzheader_str));
+}
+
+static unsigned addbyte_crc32(unsigned crc, int val)
+{
+	unsigned char tmp = val;
+
+	return crc32(crc, &tmp, 1);
+}
+
+int main(int argc, char **argv)
+{
+	char /* *progname = *argv, */ help_option[] = "-h", *help_option_ptr = help_option;
+
+	enum main_returned_enum returned = err_none;
+
+	char *infilename = 0, *outfilename = 0;
+	FILE *infile = NULL, *outfile = NULL;
+
+	int verbose = 0, show_name = 0, show_comment = 0, overwrite = 0,
+	    show_header_crc = 0, show_text_flag = 0,
+	    set_text_flag = -1, activate_header_crc = -1;
+
+	struct gzheader_str header;
+	unsigned header_crc = 0, calculated_header_crc;
+	unsigned short extrafield_len = 0;
+	char *extrafield = 0;
+	char *name = 0, *comment = 0;
+
+	char *newcomment = 0, *newprecomment = 0, *newpostcomment = 0, *newname = 0;
+	char checkprespc = 0, checkpostspc = 0;
+	char *ptr;
+	int cpt;
+
+	if (argc == 1) {
+		argc = 2;
+		argv = &help_option_ptr;
+	} else {
+		argc--;
+		argv++;
+	}
+
+	for (cpt = 0; cpt < argc; cpt++) {
+		if (argv[cpt][0] == '-' && argv[cpt][1] != '\0') {
+			switch (argv[cpt][1]) {
+			case 'V':
+				printf("%s\n", version);
+				return err_none;
+			case 'h':
+				printf("%s\n", usage);
+				return err_none;
+			case 'v':
+				verbose = 1;
+				break;
+			case 'f':
+				if (argv[cpt][2] == '\0')
+					overwrite = 1;
+				break;
+			case 'b':
+				if (argv[cpt][2] == '\0') {
+					show_text_flag = 1;
+					break;
+				}
+				if (argv[cpt][2] == '0') {
+					show_text_flag = 2;	/* raw form */
+					break;
+				}
+				if (argv[cpt][2] != '='
+				    || (argv[cpt][3] != '0' && argv[cpt][3] != '1')) {
+					PRINTERR(malformed_param, argv[cpt][1]);
+					return err_malformed_param;
+				}
+				set_text_flag = (argv[cpt][3] == '1');
+				break;
+			case 'k':
+				if (argv[cpt][2] == '\0') {
+					show_header_crc = 1;
+					break;
+				}
+				if (argv[cpt][2] == '0') {
+					show_header_crc = 2;	/* raw form */
+					break;
+				}
+				if (argv[cpt][2] != '='
+				    || (argv[cpt][3] != '0' && argv[cpt][3] != '1')) {
+					PRINTERR(malformed_crc_param);
+					return err_malformed_crc_param;
+				}
+				activate_header_crc = (argv[cpt][3] == '1');
+				break;
+			case 'n':
+				if (argv[cpt][2] == '\0') {
+					show_name = 1;
+					break;
+				}
+				if (argv[cpt][2] == '0') {
+					show_name = 2;
+					break;
+				}
+				if (argv[cpt][2] != '=') {
+					PRINTERR(malformed_param, argv[cpt][1]);
+					return err_malformed_param;
+				}
+				newname = &argv[cpt][3];
+				break;
+			case 'c':
+				if (argv[cpt][2] == '\0') {
+					show_comment = 1;
+					break;
+				}
+				if (argv[cpt][2] == '0') {
+					show_comment = 2;
+					break;
+				}
+				if (argv[cpt][2] != '=') {
+					PRINTERR(malformed_param, argv[cpt][1]);
+					return err_malformed_param;
+				}
+				newcomment = &argv[cpt][3];
+				break;
+			case 'p':{
+					unsigned len;
+					unsigned char checkspc;
+					char *start;
+
+					len = 2;
+					switch (argv[cpt][len]) {
+					case 's':
+						checkspc = ' ';
+						len++;
+						break;
+					case 'l':
+						checkspc = '\n';
+						len++;
+						break;
+					case 't':
+						checkspc = '\t';
+						len++;
+						break;
+					default:
+					case '=':
+						checkspc = '\0';
+						break;
+					}
+
+					if (argv[cpt][len++] != '=') {
+						PRINTERR(malformed_param, argv[cpt][1]);
+						return err_malformed_param;
+					}
+					start = &argv[cpt][len];
+					len = strlen(start) + 1;
+					if (*start == 0) {
+						if (newprecomment == 0)
+							checkprespc = checkspc;
+					} else if (newprecomment == 0) {
+						newprecomment = malloc(len);
+						if (newprecomment == 0)
+							goto label_not_enough_memory;
+						checkprespc = checkspc;
+						strcpy(newprecomment, start);
+					} else {
+						char *tmp = malloc(strlen(newprecomment)
+									 + len + 1);
+						if (tmp == 0)
+							goto label_not_enough_memory;
+						strcpy(tmp, start);
+						/* last char: */
+						ptr = &tmp[len - 2];
+						if (checkspc != '\0' && *ptr != checkspc
+							&& newprecomment[0] != checkspc)
+							*++ptr = checkspc;
+						ptr++;
+						strcpy(ptr, newprecomment);
+						free(newprecomment);
+						newprecomment = tmp;
+					}
+				}
+				break;
+			case 'a':{
+					unsigned len;
+					unsigned char checkspc;
+					char *start;
+
+					len = 2;
+					switch (argv[cpt][len]) {
+					case 's':
+						checkspc = ' ';
+						len++;
+						break;
+					case 'l':
+						checkspc = '\n';
+						len++;
+						break;
+					case 't':
+						checkspc = '\t';
+						len++;
+						break;
+					case '=':
+					default:
+						checkspc = '\0';
+						break;
+					}
+
+					if (argv[cpt][len++] != '=') {
+						PRINTERR(malformed_param, argv[cpt][1]);
+						return err_malformed_param;
+					}
+					start = &argv[cpt][len];
+					len = strlen(start) + 1;
+					if (*start == 0) {
+						if (newpostcomment == 0)
+							checkpostspc = checkspc;
+					} else if (newpostcomment == 0) {
+						newpostcomment = malloc(len);
+						if (newpostcomment == 0)
+							goto label_not_enough_memory;
+						checkpostspc = checkspc;
+						strcpy(newpostcomment, start);
+					} else {
+						ptr = realloc(newpostcomment,
+							 strlen(newpostcomment) + len + 1);
+						if (ptr == 0)
+							goto label_not_enough_memory;
+						newpostcomment = ptr;
+						/* last char: */
+						ptr = &newpostcomment[strlen(newpostcomment) - 1];
+						if (checkspc != '\0' && *ptr != checkspc
+						    && *start != checkspc)
+							*++ptr = checkspc;
+						ptr++;
+						strcpy(ptr, start);
+					}
+				}
+				break;
+			default:
+				PRINTERR(unknown_action, argv[cpt][1]);
+				return err_unknown_action;
+			}
+		} else if (infilename == 0) {
+			infilename = argv[cpt];
+		} else if (outfilename == 0) {
+			outfilename = argv[cpt];
+		} else {
+			PRINTERR(too_many_param, argv[cpt]);
+			return err_too_many_param;
+		}
+	}
+
+	/*
+	 * Check option validity:
+	 */
+	if (infilename == 0) {
+		PRINTERR(no_input_file);
+		return err_no_input_file;
+	}
+
+	if (newname || newcomment || newpostcomment || newprecomment
+		|| activate_header_crc != -1 || set_text_flag != -1) {
+		if (outfilename == 0) {
+			if (overwrite) {
+				outfilename = infilename;
+			} else {
+				PRINTERR(no_output_file);
+				return err_no_output_file;
+			}
+		}
+	}
+
+	/*
+	 * Read the input file:
+	 */
+	if (!strcmp(infilename, "-")) {
+		infile = stdin;
+		VERBOSE(treating_intput_file, standart_input);
+	} else {
+		infile = fopen(infilename, "r");
+		if (infile == NULL) {
+			PRINTERR(cannot_open_input_file, infilename);
+			return err_cannot_open_input_file;
+		}
+		VERBOSE(treating_intput_file, infilename);
+	}
+
+	ptr = (char *)&header;
+	for (cpt = 0; cpt < sizeof(header); cpt++) {
+		int tmp = fgetc(infile);
+		if (tmp == EOF) {
+			if (!ferror(infile))
+				goto label_not_gzip_file;
+			else
+				goto label_read_input_file_error;
+		}
+		*ptr++ = tmp;
+	}
+
+	calculated_header_crc = initheader_crc32(&header);
+
+	if (header.signature_0x8B1F != 0x8B1F || header.compression_method != Z_DEFLATED
+		|| header.flags & FLAGS_unknown)
+		goto label_not_gzip_file;
+
+	if (header.flags & FLAGS_extra_field) {
+		int tmp = fgetc(infile);
+		if (tmp == EOF) {
+			if (!ferror(infile))
+				goto label_not_gzip_file;
+			else
+				goto label_read_input_file_error;
+		}
+		calculated_header_crc = addbyte_crc32(calculated_header_crc, tmp);
+		extrafield_len = tmp;
+		tmp = fgetc(infile);
+		if (tmp == EOF) {
+			if (!ferror(infile))
+				goto label_not_gzip_file;
+			else
+				goto label_read_input_file_error;
+		}
+		calculated_header_crc = addbyte_crc32(calculated_header_crc, tmp);
+		extrafield_len |= tmp << 8;
+		VERBOSE(extra_field_present, extrafield_len);
+
+		if (extrafield_len != 0) {
+			if ((extrafield = malloc(extrafield_len)) == 0)
+				goto label_not_enough_memory;
+		}
+		for (cpt = 0; cpt < extrafield_len; cpt++) {
+			tmp = fgetc(infile);
+			if (tmp == EOF) {
+				if (!ferror(infile))
+					goto label_not_gzip_file;
+				else
+					goto label_read_input_file_error;
+			}
+			calculated_header_crc = addbyte_crc32(calculated_header_crc, tmp);
+			extrafield[cpt] = tmp;
+		}
+	}
+
+	if (header.flags & FLAGS_orig_name) {
+		unsigned name_len = 0, name_alloced = 0;
+		int tmp;
+
+		do {
+			tmp = fgetc(infile);
+			if (tmp == EOF) {
+				if (!ferror(infile))
+					goto label_not_gzip_file;
+				else
+					goto label_read_input_file_error;
+			}
+			calculated_header_crc = addbyte_crc32(calculated_header_crc, tmp);
+			if (name_len >= name_alloced) {
+				if (name != 0) {
+					if ((ptr = realloc(name, name_alloced += 1024)) == 0)
+						goto label_not_enough_memory;
+					name = ptr;
+				} else {
+					if ((name = malloc(name_alloced = 1024)) == 0)
+						goto label_not_enough_memory;
+				}
+			}
+			name[name_len++] = tmp;
+		} while (tmp != '\0');
+		VERBOSE(original_name, name);
+	}
+
+	if (header.flags & FLAGS_comment) {
+		unsigned comment_len = 0, comment_alloced = 0;
+		int tmp;
+
+		do {
+			tmp = fgetc(infile);
+			if (tmp == EOF) {
+				if (!ferror(infile))
+					goto label_not_gzip_file;
+				else
+					goto label_read_input_file_error;
+			}
+			calculated_header_crc = addbyte_crc32(calculated_header_crc, tmp);
+			if (comment_len >= comment_alloced) {
+				if (comment != 0) {
+					if ((ptr = realloc(comment, comment_alloced += 1024))
+						== 0)
+						goto label_not_enough_memory;
+					comment = ptr;
+				} else {
+					if ((comment = malloc(comment_alloced = 1024)) == 0)
+						goto label_not_enough_memory;
+				}
+			}
+			comment[comment_len++] = tmp;
+		} while (tmp != '\0');
+		VERBOSE(comment_present, comment);
+	}
+
+	if (header.flags & FLAGS_header_crc) {
+		int tmp = fgetc(infile);
+		if (tmp == EOF) {
+			if (!ferror(infile))
+				goto label_not_gzip_file;
+			else
+				goto label_read_input_file_error;
+		}
+		header_crc = tmp;
+		tmp = fgetc(infile);
+		if (tmp == EOF) {
+			if (!ferror(infile))
+				goto label_not_gzip_file;
+			else
+				goto label_read_input_file_error;
+		}
+		header_crc |= tmp << 8;
+		calculated_header_crc &= 0xFFFF;
+		if (show_header_crc == 2)
+			printf("0x%X\n", header_crc);
+		else if (show_header_crc != 0)
+			printf(show_header_crc_msg, infilename, header_crc);
+		VERBOSE(header_crc_present, header_crc);
+		if (calculated_header_crc != header_crc) {
+			PRINTERR(bad_header_crc, header_crc, calculated_header_crc);
+			returned = err_bad_header_crc;
+			goto label_end;
+		}
+	} else {
+		if (show_header_crc != 0 && show_header_crc != 2)
+			printf(no_CRC_to_show_msg, infilename);
+	}
+
+	/*
+	 * Treat commands:
+	 */
+
+	if (show_name == 2) {
+		if (name != 0)
+			printf("%s\n", name);
+	} else if (show_name) {
+		if (name != 0)
+			printf(show_name_msg, infilename, name);
+		else
+			printf(no_name_to_show_msg, infilename);
+	}
+
+	if (show_comment == 2) {
+		if (comment != 0)
+			printf("%s\n", comment);
+	} else if (show_comment) {
+		if (comment != 0)
+			printf(show_comment_msg, infilename, comment);
+		else
+			printf(no_comment_to_show_msg, infilename);
+	}
+
+	if (show_text_flag == 2) {
+		printf("%u\n", header.flags & FLAGS_ascii);
+	} else if (show_text_flag) {
+		if (header.flags & FLAGS_ascii)
+			printf(show_textflags_text_msg, infilename);
+		else
+			printf(show_textflags_binary_msg, infilename);
+	}
+
+	if (set_text_flag != -1) {
+		if (set_text_flag == 0) {
+			header.flags &= ~FLAGS_ascii;
+			VERBOSE(clear_probablytext_flag);
+		} else {
+			header.flags |= FLAGS_ascii;
+			VERBOSE(set_probablytext_flag);
+		}
+	}
+
+	if (activate_header_crc != -1) {
+		if (activate_header_crc) {
+			header.flags |= FLAGS_header_crc;
+			VERBOSE(enabling_header_crc);
+		} else {
+			header.flags &= ~FLAGS_header_crc;
+			VERBOSE(disabling_header_crc);
+		}
+	}
+
+	if (newname) {
+		if (*newname == 0) {
+			header.flags &= ~FLAGS_orig_name;
+			VERBOSE(removing_name);
+		} else {
+			header.flags |= FLAGS_orig_name;
+			VERBOSE(changing_name, newname);
+			if (name)
+				free(name);
+			name = malloc(strlen(newname) + 1);
+			strcpy(name, newname);
+		}
+	}
+
+	if (newcomment) {
+		if (*newcomment == '\0') {
+			VERBOSE(removing_comment);
+			if (comment)
+				free(comment);
+			comment = 0;
+			header.flags &= ~FLAGS_comment;
+		} else {
+			VERBOSE(replacing_comment, newcomment);
+			if (comment)
+				free(comment);
+			comment = malloc(strlen(newcomment) + 1);
+			strcpy(comment, newcomment);
+			header.flags |= FLAGS_comment;
+		}
+	}
+
+	if (newprecomment) {
+		if ((header.flags & FLAGS_comment) == 0) {
+			VERBOSE(adding_comment, newprecomment);
+			comment = malloc(strlen(newprecomment) + 1);
+			if (comment == 0)
+				goto label_not_enough_memory;
+			strcpy(comment, newprecomment);
+			/* last char: */
+			ptr = &comment[strlen(comment)];
+			if (checkprespc != '\0' && *ptr != checkprespc) {
+				*++ptr = checkprespc;
+				*++ptr = '\0';
+			}
+			free(newprecomment);
+			newprecomment = 0;
+		} else {
+			VERBOSE(prepending_comment, newprecomment);
+			ptr = realloc(newprecomment, strlen(newprecomment) + 1
+							+ strlen(comment) + 1);
+			if (ptr == 0)
+				goto label_not_enough_memory;
+			newprecomment = ptr;
+			/* last char: */
+			ptr = &newprecomment[strlen(newprecomment)];
+			if (checkprespc != '\0'
+			    && *ptr != checkprespc && comment[0] != checkprespc)
+				*++ptr = checkprespc;
+			ptr++;
+			strcpy(ptr, comment);
+			free(comment);
+			comment = newprecomment;
+			newprecomment = 0;
+		}
+		header.flags |= FLAGS_comment;
+	}
+
+	if (newpostcomment) {
+		if ((header.flags & FLAGS_comment) == 0) {
+			VERBOSE(adding_comment, newpostcomment);
+			comment = malloc(strlen(newpostcomment) + 1);
+			if (comment == 0)
+				goto label_not_enough_memory;
+			strcpy(comment, newpostcomment);
+			/* last char: */
+			ptr = &comment[strlen(comment)];
+			if (checkpostspc != '\0' && *ptr != checkpostspc) {
+				*++ptr = checkpostspc;
+				*++ptr = '\0';
+			}
+			free(newpostcomment);
+			newpostcomment = 0;
+		} else {
+			VERBOSE(appending_comment, newpostcomment);
+			ptr = realloc(comment, strlen(comment)
+						 + 1 + strlen(newpostcomment) + 1);
+			if (ptr == 0)
+				goto label_not_enough_memory;
+			comment = ptr;
+			/* last char: */
+			ptr = &comment[strlen(comment) - 1];
+			if (checkpostspc != '\0'
+			    && *ptr != checkpostspc && newpostcomment[0] != checkpostspc)
+				*++ptr = checkpostspc;
+			ptr++;
+			strcpy(ptr, newpostcomment);
+			free(newpostcomment);
+			newpostcomment = 0;
+		}
+		header.flags |= FLAGS_comment;
+	}
+
+	/*
+	 * Write the file back:
+	 */
+
+	if (outfilename != 0) {
+		struct stat inbuf;
+		char *full_content = 0;
+		unsigned full_length = 0;
+
+		if (fstat(fileno(infile), &inbuf) != -1) {
+			full_content = malloc(inbuf.st_size);	/* bit too much but... */
+			if (full_content != 0) {
+				char *ptr = full_content;
+				for (;;) {
+					int tmp = fgetc(infile);
+
+					if (tmp == EOF) {
+						if (ferror(infile)) {
+							free(full_content);
+							goto label_read_input_file_error;
+						}
+						break;
+					}
+					full_length++;
+					if (full_length >= inbuf.st_size) {
+						free(full_content);
+						goto label_read_input_file_error;
+					}
+					*ptr++ = tmp;
+				}
+			} else if (outfilename == infilename)
+				goto label_read_input_file_error;
+		}
+
+		if (!strcmp(outfilename, "-")) {
+			outfile = stdout;
+			VERBOSE(treating_output_file, standart_output);
+		} else {
+			if (overwrite == 0) {
+				struct stat buf;
+				if (stat(outfilename, &buf) != -1 && errno != ENOENT) {
+					errno = 0;
+					PRINTERR(outfile_already_exists, outfilename);
+					returned = err_outfile_already_exists;
+					goto label_end;
+				}
+				errno = 0;
+			}
+			outfile = fopen(outfilename, "w");
+			if (outfile == NULL) {
+				PRINTERR(cannot_open_output_file, outfilename);
+				returned = err_cannot_open_output_file;
+				goto label_end;
+			}
+			VERBOSE(treating_output_file, outfilename);
+		}
+
+		ptr = (char *)&header;
+		for (cpt = 0; cpt < sizeof(header); cpt++) {
+			if (fputc(*ptr++, outfile) == EOF)
+				goto label_cannot_write_to_file;
+		}
+
+		calculated_header_crc = initheader_crc32(&header);
+
+		if (header.flags & FLAGS_extra_field) {
+			ptr = extrafield;
+			if (fputc(extrafield_len, outfile) == EOF
+				|| fputc(extrafield_len >> 8, outfile) == EOF)
+				goto label_cannot_write_to_file;
+			calculated_header_crc = addbyte_crc32(calculated_header_crc,
+								extrafield_len);
+			calculated_header_crc = addbyte_crc32(calculated_header_crc,
+								extrafield_len >> 8);
+
+			for (cpt = 0; cpt < extrafield_len; cpt++) {
+				if (fputc(*ptr, outfile) == EOF)
+					goto label_cannot_write_to_file;
+				calculated_header_crc = addbyte_crc32(calculated_header_crc,
+								*ptr);
+				ptr++;
+			}
+		}
+		if (header.flags & FLAGS_orig_name) {
+			unsigned name_len = strlen(name) + 1;
+
+			ptr = name;
+			for (cpt = 0; cpt < name_len; cpt++) {
+				if (fputc(*ptr, outfile) == EOF)
+					goto label_cannot_write_to_file;
+				calculated_header_crc = addbyte_crc32(calculated_header_crc,
+								*ptr);
+				ptr++;
+			}
+		}
+		if (header.flags & FLAGS_comment) {
+			unsigned comment_len = strlen(comment) + 1;
+
+			ptr = comment;
+			for (cpt = 0; cpt < comment_len; cpt++) {
+				if (fputc(*ptr, outfile) == EOF)
+					goto label_cannot_write_to_file;
+				calculated_header_crc = addbyte_crc32(calculated_header_crc,
+								*ptr);
+				ptr++;
+			}
+		}
+		if (header.flags & FLAGS_header_crc) {
+			calculated_header_crc &= 0xFFFF;
+			if (fputc(calculated_header_crc, outfile) == EOF
+				|| fputc(calculated_header_crc >> 8, outfile) == EOF)
+				goto label_cannot_write_to_file;
+			if (show_header_crc == 2)
+				printf("0x%X\n", header_crc);
+			else if (show_header_crc != 0)
+				printf(show_header_crc_msg, infilename, header_crc);
+			VERBOSE(new_header_crc, calculated_header_crc);
+		}
+
+		if (full_content == 0) {
+			for (;;) {
+				int tmp = fgetc(infile);
+
+				if (tmp == EOF) {
+					if (ferror(infile))
+						goto label_read_input_file_error;
+					break;
+				}
+				if (fputc(tmp, outfile) == EOF)
+					goto label_cannot_write_to_file;
+			}
+		} else {
+			if (fwrite(full_content, 1, full_length, outfile) != full_length)
+				goto label_cannot_write_to_file;
+		}
+	}
+
+      label_end:
+	if (extrafield != 0)
+		free(extrafield);
+	if (name != 0)
+		free(name);
+	if (comment != 0)
+		free(comment);
+
+	if (infile != NULL) {
+		if (fclose(infile) == EOF) {
+			PRINTERR(cannot_close_input_file, infilename);
+			returned = err_cannot_close_input_file;
+		}
+	}
+
+	if (outfile != NULL) {
+		if (fclose(outfile) == EOF) {
+			PRINTERR(cannot_close_output_file, outfilename);
+			returned = err_cannot_close_output_file;
+		}
+	}
+	return returned;
+
+      label_not_gzip_file:
+	PRINTERR(not_gzip_file, infilename, header.signature_0x8B1F);
+	returned = err_not_gzip_file;
+	goto label_end;
+
+      label_not_enough_memory:
+	PRINTERR(not_enough_memory);
+	returned = err_not_enough_memory;
+	goto label_end;
+
+      label_read_input_file_error:
+	PRINTERR(read_input_file_error, infilename);
+	returned = err_read_input_file_error;
+	goto label_end;
+
+      label_cannot_write_to_file:
+	PRINTERR(cannot_write_to_file, outfilename);
+	returned = err_cannot_write_to_file;
+	goto label_end;
+}
diff -uprN -X linux-2.6.14-rc3/Documentation/dontdiff -x '*.orig' -x '*.cmd' -x '.tmp*' -x '*.o' -x '*.ko' -x '*.a' -x '*.so' -x '.config*' -x asm-offsets.s -x asm_offsets.h -x vmlinux.lds -x vsyscall.lds -x '*.mod.c' -x Module.symvers -x consolemap_deftbl.c -x defkeymap.c -x classlist.h -x devlist.h -x asm -x md -x scsi -x logo -x config -x .version -x zconf.tab.h -x elfconfig.h -x System.map -x zconf.tab.c -x lex.zconf.c -x compile.h -x config_data.h -x version.h -x crc32table.h -x autoconf.h -x gen-devlist -x initramfs_list linux-2.6.14-rc3/scripts/gzparam.c linux-2.6.14-rc3-1/scripts/gzparam.c
--- linux-2.6.14-rc3/scripts/gzparam.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14-rc3-1/scripts/gzparam.c	2005-10-04 15:45:27.104601376 +0200
@@ -0,0 +1,209 @@
+/*
+ * This file "gzparam.c" is licensed with the same license as the LINUX kernel.
+ * Copyright 2004, Etienne Lorrain (etienne dot lorrain at gujin dot org)
+ *
+ *  The main use of this file is to produce a "Gujin native bootable
+ * file" i.e. a LINUX kernel with a "kgz" extension, more exactly
+ * the option part which is going to be written in the comment field
+ * of the GZIP file (as documented in the GZIP format).
+ * See linux/Makefile to know how the following is used for target
+ * *.kgz - simply by using the "gzcopy" utility.
+ *
+ * This standalone executable named "gzparam" is just displaying a
+ * line containing zero or more field of the pattern
+ * "<variable>=0x<hexavalue>" (i.e. no decimal), to define for which
+ * CPU this kernel is for, which video mode can be used (for instance
+ * forbid VESA 1.0 graphic modes), where to load the kernel
+ * (default 0x100000 - other value needs kernel modifications but
+ * would free DMA memory), where to copy the Linux parameter 4 Kb page
+ * in real-mode memory and the like.
+ *
+ * Because most values depend on compilation switches of the
+ * Linux kernel - we have to use an up-to-date file reflecting
+ * the configuration options - but because we may cross compile
+ * the kernel we have here to use the host compiler (with maybe
+ * different optimisation options). The simpler seems to use
+ * the file "linux/include/linux/autoconf.h". This file is
+ * automagically updated by "make menuconfig".
+ *
+ * First version has been written by Etienne Lorrain in December 2004.
+ */
+
+#include <stdio.h>
+
+#include "../include/linux/autoconf.h"
+
+/*
+ *  Those are not used for now, Gujin will use its default behaviour
+ * because we do not display them on stdout:
+ */
+const unsigned runadr = 0, minram = 0, option = 0;
+
+/*
+ * Gujin-0.9 will not be able to load the kernel being generated,
+ * the first acceptable version is Gujin-1.0:
+ */
+const unsigned min_gujin_version = 0x102;
+
+/*
+ *  Keep for now the default of 0x80000 (linear address) for paramadr:
+ * it has to be a "free" real mode memory address, and if the user is using
+ * a DOS bootloader the bootloader code can be quite high in memory when
+ * using a lot of DOS drivers (like DOS USB disk drivers).
+ *  realfct_size is calculated on-line in Makefile, it is the size of
+ * the real-mode code output section of the vmlinux ELF file.
+ */
+const unsigned paramadr = 0 /* , realfct_size = 0 */ ;
+
+/*
+ * Since 2.6.13, this can be set up manually to free DMA-able memory,
+ * i.e. memory below 16 Mbytes. Also old PC may have a hole in between
+ * 15 and 16 Mbytes so starting the kernel at 16 Mbytes is better,
+ * as long as you have more than 16 Mbytes of memory...
+ * This PHYSICAL_START = 0x1000000 is only bootable with Gujin-1.2+
+ */
+#if defined (CONFIG_PHYSICAL_START) && CONFIG_PHYSICAL_START != 0x100000
+const unsigned loadadr = CONFIG_PHYSICAL_START;
+#endif
+
+/*
+ * Q: Why check the processor here (i.e. before even calling linux_set_params(),
+ *    we could check the processor and exit with an error code...) ?
+ * A: First the processor may not be an ia32 one (x86_64, ia64 or even
+ *    PowerPC) and the compilation of linux_set_params() may use ia32
+ *    instructions (MMX) not defined for the current processor used.
+ *    This mask shall say: do not even try to execute the first assembly
+ *    instruction of linux_set_params() if corresponding bit is set.
+ *    It may still be easier to refuse a CPU here (Pentium code on an i386)
+ */
+/* Please help checking and completing this array.
+   filed from www.sandpile.org CPUID.
+   The family of your processor is displayed at Gujin startup.
+   In case of problem, boot a bare DOS floppy and use "dbgload.exe" to
+   (try to) load a standard vmlinuz kernel - the file a:DBG will show
+   all usefull information.
+   If load fails, exit "dbgload.exe" by ^C and not by reboot to close
+   the DBG file.
+   If everything fails, you can also debug to a serial line or a printer. */
+const unsigned maskcpu = 0x80000000	/* refuse to start if no IA32 BIOS (not a PC) */
+	//| 0x40000000	/* refuse to start from DOS/windows */
+	//| 0x20000000	/* refuse to start from EMM386/virtual environment */
+	| (0x000180FF	/* bits used for precise CPU type compatibility */
+	// & ~(1 << 0)	/* can run on 8086 */
+	// & ~(1 << 1)	/* can run on 80186 */
+	// & ~(1 << 2)	/* can run on 80286 */
+#ifdef CONFIG_M386
+	& ~(1 << 3)	/* can run on 80386, i.e. cannot set AC i.e. bit 18 of flags */
+	& ~(1 << 4)	/* can run on 80486, i.e. CPUID family = 4 or no CPUID */
+	& ~(1 << 5)	/* can run on 80586, i.e. CPUID family == 5 */
+	& ~(1 << 6)	/* can run on 80686, i.e. CPUID family == 6 */
+	& ~(1 << 15)	/* can run on 80F86, i.e. CPUID family == (0xF + 0) extended_family */
+ /* HELPME: Is an IA64 compatible enough to boot a CONFIG_M386 kernel? I do not think so. */
+#elif defined (CONFIG_M486)
+	& ~(1 << 4)	/* can run on 80486, i.e. CPUID family = 4 or no CPUID */
+	& ~(1 << 5)	/* can run on 80586, i.e. CPUID family == 5 */
+	& ~(1 << 6)	/* can run on 80686, i.e. CPUID family == 6 */
+	& ~(1 << 15)	/* can run on 80F86, i.e. CPUID family == (0xF + 0) extended_family */
+#elif defined (CONFIG_M586) || defined (CONFIG_MK6) \
+	|| defined (CONFIG_MCRUSOE) || defined (CONFIG_MWINCHIPC6)
+	& ~(1 << 5)	/* can run on 80586, i.e. CPUID family == 5 */
+	& ~(1 << 6)	/* can run on 80686, i.e. CPUID family == 6 */
+	& ~(1 << 15)	/* can run on 80F86, i.e. CPUID family == (0xF + 0) extended_family */
+#elif defined (CONFIG_M686) || defined (CONFIG_MPENTIUMII) \
+	|| defined (CONFIG_MPENTIUMIII) || defined (CONFIG_MPENTIUMM) \
+	|| defined (CONFIG_MK7) || defined (CONFIG_MWINCHIP2) \
+	|| defined (CONFIG_MCYRIXIII) || defined (CONFIG_MVIAC3_2)
+	& ~(1 << 6)	/* can run on 80686, i.e. CPUID family == 6 */
+	& ~(1 << 15)	/* can run on 80F86, i.e. CPUID family == (0xF + 0) extended_family */
+#elif defined (CONFIG_MPENTIUM4) || defined (CONFIG_MK8)
+	& ~(1 << 15)	/* can run on 80F86, i.e. CPUID family == (0xF + 0) extended_family */
+#elif defined (CONFIG_IA64)
+	& ~(1 << 7)	/* can run on 80786, i.e. CPUID family == 7 */
+	& ~(1 << 16)	/* can run on 80?86, i.e. CPUID family == (0xF + 1) extended_family */
+#elif defined (CONFIG_IA64_2)
+	& ~(1 << 16)	/* can run on 80?86, i.e. CPUID family == (0xF + 1) extended_family */
+#endif
+	);
+
+/* Probably plenty of other checks to do here... see vmlinuz.h */
+const unsigned maskDflags = 0
+#ifndef CONFIG_MATH_EMULATION
+	| (1 << 0)
+#endif
+#ifdef CONFIG_M586TSC
+	| (1 << 4)
+#endif
+#ifdef CONFIG_X86_CMPXCHG
+	| (1 << 8)
+#endif
+#ifdef CONFIG_M586MMX
+	| (1 << 23)
+#endif
+	;
+const unsigned maskCflags = 0
+#ifdef CONFIG_X86_CMPXCHG16B
+	| (1 << 13)
+#endif
+	;
+
+/* unused on PCs: */
+const unsigned maskBflags = 0;
+
+/* AMD CPUID 0x80000001: */
+const unsigned maskAflags = 0
+#ifdef CONFIG_X86_64
+	| (1 << 29)
+#endif
+#ifdef CONFIG_X86_USE_3DNOW
+	| (1 << 31)
+#endif
+	;
+
+/*
+ * maskvesa and maskresolution are only checked when the loader has
+ * screen management compiled-in, i.e. not for tiny.img nor tiny.exe
+ * version of Gujin.
+ * Set them to zero to completely disable those check in Gujin.
+ */
+const unsigned maskvesa = 0
+#ifndef CONFIG_FB_VESA
+	| (1 << 0)	/* Cannot boot in MASKVESA_1BPP */
+	| (1 << 1)	/* Cannot boot in MASKVESA_2BPP */
+	| (1 << 3)	/* Cannot boot in MASKVESA_4BPP */
+	| (1 << 7)	/* Cannot boot in MASKVESA_8BPP */
+	| (1 << 14)	/* Cannot boot in MASKVESA_15BPP */
+	| (1 << 15)	/* Cannot boot in MASKVESA_16BPP */
+	| (1 << 23)	/* Cannot boot in MASKVESA_24BPP */
+	| (1 << 31)	/* Cannot boot in MASKVESA_32BPP */
+#endif
+#if defined (CONFIG_VGA_CONSOLE) || defined (CONFIG_MDA_CONSOLE)
+	| (1 << 16)	/* able to boot in text mode */
+#endif
+	// | (1 << 17)	/* not able to boot in VESA1 mode */
+#ifdef CONFIG_FB_VESA
+	| (1 << 18)	/* able to boot in VESA2 linear mode */
+#endif
+	// | (1 << 19)	/* force VESA1 if in VESA2 */
+	| (1 << 20)	/* Cannot handle VGA graphic modes */
+	;
+const unsigned maskresolution = 0
+	| (1 << 0)	/* exclude MASKRESOLUTION_40cols */
+	| (1 << 15)	/* exclude MASKRESOLUTION_320x200 */
+	| (1 << 16)	/* exclude MASKRESOLUTION_320x400 */
+	// | (1 << 31)	/* not listed invalid */
+	;
+
+int main (int argc, char **argv) {
+	printf ("min_gujin_version=0x%X maskcpu=0x%X ",
+		min_gujin_version, maskcpu);
+	if (maskDflags != 0)
+		printf ("maskDflags=0x%X ", maskDflags);
+	if (maskAflags != 0)
+		printf ("maskAflags=0x%X ", maskAflags);
+#if defined (CONFIG_PHYSICAL_START) && CONFIG_PHYSICAL_START != 0x100000
+	printf ("loadadr=0x%X ", loadadr);
+#endif
+	printf ("maskvesa=0x%X maskresolution=0x%X\n",
+		maskvesa, maskresolution);
+	return 0;
+	}

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2005-10-11 15:23 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-10-06 13:39 [PATCH 1/3] Gujin linux.kgz boot format Etienne Lorrain
  -- strict thread matches above, loose matches on Subject: below --
2005-10-11 13:16 Etienne Lorrain
2005-10-06  9:46 Etienne Lorrain
2005-10-07 14:46 ` Pavel Machek
2005-10-10 11:23   ` Etienne Lorrain
2005-10-10 11:56     ` Pavel Machek
2005-10-10 13:09       ` Etienne Lorrain
2005-10-10 13:19         ` Pavel Machek
2005-10-10 14:31           ` Etienne Lorrain
2005-10-10 19:21             ` Pavel Machek
2005-10-10 19:35             ` Kalin KOZHUHAROV
2005-10-11 13:56 ` Denis Vlasenko
2005-10-11 15:23   ` Etienne Lorrain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).