[RFC] Win32 port of the userspace tools using MinGW.
OK, I haven't quite gotten around to posting the Windows kernel driver source that goes with this. So I'm not asking that this patch be merged, since nobody else can use it yet. :-) I'd love to get review, though: Does this look like it's in a mergeable state? I'm happy with it, but do I need to change anything to make it acceptable to you folks? This patch requires basically all the other patches I've posted. Makefile.in |1 + include/byteswap.h| 39 +++ kexec/Makefile|6 + kexec/arch/i386/Makefile |2 + kexec/arch/i386/kexec-x86.c |2 + kexec/arch/i386/x86-linux-setup.c |4 + kexec/kexec-syscall.h |7 ++ kexec/kexec.c |4 + kexec/kexec.h | 10 ++ kexec/win32.c | 214 + 10 files changed, 289 insertions(+), 0 deletions(-) create mode 100644 include/byteswap.h create mode 100644 kexec/win32.c diff --git a/Makefile.in b/Makefile.in index b51c3a1..bdd6ba7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -24,6 +24,7 @@ ARCH = @ARCH@ OBJDIR = @OBJDIR@ target = @target@ host = @host@ +host_os= @host_os@ # Compiler for building kexec CC = @CC@ diff --git a/include/byteswap.h b/include/byteswap.h new file mode 100644 index 000..cd5a726 --- /dev/null +++ b/include/byteswap.h @@ -0,0 +1,39 @@ +/* byteswap.h + +Copyright 2005 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file CYGWIN_LICENSE for +details. */ + +#ifndef _BYTESWAP_H +#define _BYTESWAP_H + +#ifdef __cplusplus +extern C { +#endif + +static __inline unsigned short +bswap_16 (unsigned short __x) +{ + return (__x 8) | (__x 8); +} + +static __inline unsigned int +bswap_32 (unsigned int __x) +{ + return (bswap_16 (__x 0x) 16) | (bswap_16 (__x 16)); +} + +static __inline unsigned long long +bswap_64 (unsigned long long __x) +{ + return (((unsigned long long) bswap_32 (__x 0xull)) 32) | (bswap_32 (__x 32)); +} + +#ifdef __cplusplus +} +#endif +#endif /* _BYTESWAP_H */ diff --git a/kexec/Makefile b/kexec/Makefile index a80b940..fe05340 100644 --- a/kexec/Makefile +++ b/kexec/Makefile @@ -11,16 +11,22 @@ KEXEC_SRCS = KEXEC_GENERATED_SRCS = KEXEC_SRCS += kexec/kexec.c +ifneq ($(host_os),mingw32msvc) KEXEC_SRCS += kexec/ifdown.c +endif KEXEC_SRCS += kexec/kexec-elf.c KEXEC_SRCS += kexec/kexec-elf-exec.c KEXEC_SRCS += kexec/kexec-elf-core.c KEXEC_SRCS += kexec/kexec-elf-rel.c KEXEC_SRCS += kexec/kexec-elf-boot.c KEXEC_SRCS += kexec/kexec-iomem.c +ifneq ($(host_os),mingw32msvc) KEXEC_SRCS += kexec/crashdump.c KEXEC_SRCS += kexec/crashdump-xen.c KEXEC_SRCS += kexec/phys_arch.c +else +KEXEC_SRCS += kexec/win32.c +endif KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) diff --git a/kexec/arch/i386/Makefile b/kexec/arch/i386/Makefile index f2d9636..f9dbb7b 100644 --- a/kexec/arch/i386/Makefile +++ b/kexec/arch/i386/Makefile @@ -9,7 +9,9 @@ i386_KEXEC_SRCS += kexec/arch/i386/kexec-multiboot-x86.c i386_KEXEC_SRCS += kexec/arch/i386/kexec-beoboot-x86.c i386_KEXEC_SRCS += kexec/arch/i386/kexec-nbi.c i386_KEXEC_SRCS += kexec/arch/i386/x86-linux-setup.c +ifneq ($(host_os),mingw32msvc) i386_KEXEC_SRCS += kexec/arch/i386/crashdump-x86.c +endif dist += kexec/arch/i386/Makefile $(i386_KEXEC_SRCS)\ kexec/arch/i386/kexec-x86.h kexec/arch/i386/crashdump-x86.h \ diff --git a/kexec/arch/i386/kexec-x86.c b/kexec/arch/i386/kexec-x86.c index 89ccb0b..f937856 100644 --- a/kexec/arch/i386/kexec-x86.c +++ b/kexec/arch/i386/kexec-x86.c @@ -32,6 +32,7 @@ #include crashdump-x86.h #include arch/options.h +#ifndef __MINGW32__ static struct memory_range memory_range[MAX_MEMORY_RANGES]; /* Return a sorted list of memory ranges. */ @@ -113,6 +114,7 @@ int get_memory_ranges(struct memory_range **range, int *ranges, *ranges = memory_ranges; return 0; } +#endif /* !defined(__MINGW32__) */ struct file_type file_type[] = { { multiboot-x86, multiboot_x86_probe, multiboot_x86_load, diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c index 4b9a5e5..e750d82 100644 --- a/kexec/arch/i386/x86-linux-setup.c +++ b/kexec/arch/i386/x86-linux-setup.c @@ -23,8 +23,10 @@ #include sys/types.h #include sys/stat.h #include fcntl.h +#ifndef __MINGW32__ #include sys/ioctl.h #include linux/fb.h +#endif #include unistd.h #include x86/x86-linux.h #include ../../kexec.h @@ -101,6 +103,7 @@ void setup_linux_bootloader_parameters( int setup_linux_vesafb(struct x86_linux_param_header *real_mode) { +#ifndef __MINGW32__ struct fb_fix_screeninfo fix; struct fb_var_screeninfo var; int fd; @@ -153,6 +156,7 @@ int setup_linux_vesafb(struct x86_linux_param_header
[PATCH] Update KEXEC_ARCH_* constants from Linux kernel headers.
Signed-off-by: Jamey Sharp [EMAIL PROTECTED] --- I thought I'd need this, but it turned out not to matter. I'm submitting it anyway because keeping kexec-tools in sync with the kernel kexec headers seems like a good idea. kexec/kexec-syscall.h |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h index d12a11c..2b9345f 100644 --- a/kexec/kexec-syscall.h +++ b/kexec/kexec-syscall.h @@ -82,8 +82,11 @@ static inline long kexec_reboot(void) #define KEXEC_ARCH_PPC (20 16) #define KEXEC_ARCH_PPC64 (21 16) #define KEXEC_ARCH_IA_64 (50 16) -#define KEXEC_ARCH_S390(22 16) #define KEXEC_ARCH_ARM (40 16) +#define KEXEC_ARCH_S390(22 16) +#define KEXEC_ARCH_SH (42 16) +#define KEXEC_ARCH_MIPS_LE (10 16) +#define KEXEC_ARCH_MIPS( 8 16) #define KEXEC_MAX_SEGMENTS 16 -- 1.5.4.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH] kexec based hibernation: a prototype of kexec multi-stage load
Hi! During loading, a hash table mapped from destination page to source page is used instead of original linear mapping implementation. Because the hibernated image may be very large (up to near the size of physical memory), it is very time-consuming to search a source page given the destination page, which is used to check whether an newly allocated page is in the range of allocated destination pages. This seems to be an optimization of kexec so that it becomes efficient in loading large images (containing large number of segments). Probably this can be a separate patch. IMHO, we can just first write a minimal patch where one can just switch between kernels. Once that patch is upstream, we can enhance Yes, please. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH -mm] kexec jump -v9
On Fri 2008-05-16 09:48:34, Huang, Ying wrote: On Thu, 2008-05-15 at 16:09 -0400, Vivek Goyal wrote: [...] Ok, You want to make BIOS calls. We already do that using vm86 mode and use bios real mode interrupts. So why do we need this interface? Or, IOW, how is this interface better? It can call code in 32-bit physical mode in addition to real mode. So It can be used to call EFI runtime service, especially call EFI 64 runtime service under 32-bit kernel or vice versa. The main purpose of kexec jump is for hibernation. But I think if the effort is small, why not support general 32-bit physical mode code call at same time. I believe we should focus on kexecing kernels, first. Only way to prove the effort is small is by having small followup patch, and that needs the two patches separated... Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH] kexec based hibernation: a prototype of kexec multi-stage load
On Fri, May 16, 2008 at 12:52:48PM +0800, Huang, Ying wrote: On Thu, 2008-05-15 at 19:55 -0700, Eric W. Biederman wrote: Huang, Ying [EMAIL PROTECTED] writes: The disadvantage of this solution is that kernel B must know it is original kernel (A) or kexeced kernel (B). Different code should be used by kernel A and kernel B. And after jump from A to B, jump from B to A, when jump from A to B again, kernel A must use different code from the first time. I don't know what the case is for keeping two kernels in memory and switching between them. This can be used to save the memory image of kernel B and accelerate the hibernation. The real boot of kernel B is only needed first time. I suspect a small piece of trampoline code between the two kernels could handle the case. (i.e. purgatory pays attention). That is a fundamental aspect of the design. A general purpose infrastructure with trampoline code to adapt it to whatever situation comes up. It is possible to use purgatory to deal with this problem. Jump from kernel A to kernel B Jump to entry of purgatory (purgatory_entry) purgatory save the return address (kexec_jump_back_entry_A) Purgatory set kexec_jump_back_entry for kernel B to a code segment in purgatory, say kexec_jump_back_entry_A_for_B Purgatory jump to entry point of kernel B Jump from kernel B to kernel A Jump to purgatory (kexec_jump_back_entry_A_for_B) Purgatory save the return address (kexec_jump_back_entry_B) Purgatory return to kernel A (kexec_jump_back_entry_A) Jump from kernel A to kernel B again Jump to entry of purgatory (purgatory_entry) Purgatory save the return address (kexec_jump_back_entry_A) Purgatory jump to kexec_jump_back_entry_B The disadvantage of this solution is that some information is saved in purgatory (kexec_jump_back_entry_A, kexec_jump_back_entry_B). So, purgatory must be saved too when save the memory image of kernel A or kernel B. Purgatory can be seen as a part of kernel B. But it is a little tricky to think it as a part of kernel A too. That's a good point. Remembering the actual return points in purgatory will require purgatory to be saved along with core file. I think, purgatory is a good infrastructure for transitions between the kernels but at the same time, here it is a matter of just making a call and then inspecting the stack in kexec_jump_back_entry. IMHO, we can keep it simple and not involving purgatory in later transitions. Thanks Vivek ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH] kexec based hibernation: a prototype of kexec multi-stage load
On Thu, May 15, 2008 at 11:27:58PM -0400, Vivek Goyal wrote: On Fri, May 16, 2008 at 10:56:15AM +0800, Huang, Ying wrote: On Thu, 2008-05-15 at 19:25 -0700, Eric W. Biederman wrote: Huang, Ying [EMAIL PROTECTED] writes: On Thu, 2008-05-15 at 11:39 -0700, Eric W. Biederman wrote: [...] 2) After we figure out our address read the stack pointer from a fixed location and simply set it. (This is my preference) Just for confirmation (My English is poor). Do you mean that kernel A just read the stack top as re-entry point, regardless of whether it is return address or argument 1? What I was thinking was: In kernel A() relocate_new_kernel: ... call *%eax kexec_jump_back_entry: /* This code should be PIC so figure out where we are */ call 1f 1: popl %edi subl $(1b - relocate_kernel), %edi /* Setup a safe stack */ lealPAGE_SIZE(%edi), %esp ... Then in purgatory we can read the address of kexec_jump_back_entry by examining 0(%esp) and export it in whatever fashion is sane. However we reach kexec_jump_back_entry we should be fine. Huang is making use of purgatory only for booting kernel B for the first time. Once the kernel B is booted, all the trasitions (A--B and B--A) happen without using purgatory. Just keep on jumping back and forth to kexec_jump_back_entry. Probably not using purgatory for later transitions is justified as long as kernel code is simple and small. Otherwise we will shall have to teach purgatory also of special case of resuming kernel B or booting kernel B. I think it is reasonable to enable jumping back and forth more than one time. So the following should be possible: 1. Jump from A to B (actually jump to purgatory, trigger the boot of B) 2. Jump from B to A 3. Jump from A to B again (jump to the kexec_jump_back_entry of B) 4. Jump from B to A ... So it should be possible to get the re-entry point of kernel B in kexec_jump_back_entry of kernel A too. So I think in kexec_jump_back_entry, the caller's stack should be checked to get re-entry point of peer. And the stack state is different depend on where come from, from relocate_new_kernel() or return. To me this idea also looks good. So control flow will look something as follows? relocate_new kernel: if (!preserve_context) set registers to known state. jump to purgatory. else goto jump-back-setup: jump-back-setup: - Color the stack. move $0x 0(%esp) - call %edx Thinking more about it, probably we don't have to separate out preserve context and normal kexec path. Both can transition to purgatory using call %edx. Coloring the stack should not harm in normal kexec. Thanks Vivek ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec