Move all 16-bit code into one assembly file so we don't have to rely
authorhpa <hpa>
Wed, 8 Dec 2004 04:29:22 +0000 (04:29 +0000)
committerhpa <hpa>
Wed, 8 Dec 2004 04:29:22 +0000 (04:29 +0000)
on ld working properly

memdisk/Makefile
memdisk/e820test.c
memdisk/init.S16 [deleted file]
memdisk/memdisk.h
memdisk/memdisk16.asm [moved from memdisk/init32.asm with 81% similarity]
memdisk/setup.c
memdisk/unzip.c

index e0da72e..bfa0ce6 100644 (file)
@@ -20,12 +20,13 @@ M32     := $(call gcc_ok,-m32,)
 ALIGN   := $(call gcc_ok,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0)
 
 CC       = gcc $(M32)
-CFLAGS   = -g -W -Wall -Os -fomit-frame-pointer -march=i386 $(ALIGN) \
+CFLAGS   = -g -W -Wall -Wno-sign-compare \
+          -Os -fomit-frame-pointer -march=i386 $(ALIGN) \
           -DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"'
 LDFLAGS  = -g
 INCLUDE  = -I../com32/include
 LD      = ld -m elf_i386
-NASM     = nasm -O99
+NASM     = nasm -O99 -dVERSION='"$(VERSION)"' -dDATE='"$(DATE)"'
 NINCLUDE = 
 OBJCOPY  = objcopy
 PERL     = perl
index cadd2a7..a0eb400 100644 (file)
@@ -44,7 +44,7 @@ void printranges(void) {
   }
 }
 
-int main(int argc, char *argv[])
+int main(void)
 {
   uint64_t start, len;
   uint32_t type;
diff --git a/memdisk/init.S16 b/memdisk/init.S16
deleted file mode 100644 (file)
index 0a4a330..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* $Id$ */
-/* ----------------------------------------------------------------------- *
- *   
- *   Copyright 2001 H. Peter Anvin - All Rights Reserved
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
- *   (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * init.S
- *
- * memdisk initialization code
- *
- * This module *MUST* get linked first into the image
- */
-
-#include "version.h"
-
-               .text
-               .code16
-
-/*
- * The header derives directly from the Linux kernel and must be first
- * in the binary, hence section .init
- */
-               .org 497
-setup_sects:   .byte 0                 # Filled in later
-root_flags:    .word 0
-syssize:       .word 0
-swap_dev:      .word 0
-ram_size:      .word 0
-vid_mode:      .word 0
-root_dev:      .word 0
-boot_flag:     .word 0xAA55
-
-               .globl _start
-_start:
-               jmp     start
-
- # This is the setup header, and it must start at %cs:2 (old 0x9020:2)
-       
-               .ascii  "HdrS"          # header signature
-               .word   0x0203          # header version number (>= 0x0105)
-                                       # or else old loadlin-1.5 will fail)
-realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
-start_sys_seg: .word   0x1000          # obsolete
-version_ptr:   .word   memdisk_version-0x200
-                                       # pointing to kernel version string
-
-type_of_loader:        .byte   0               # = 0, old one (LILO, Loadlin,
-                                       #      Bootlin, SYSLX, bootsect...)
-                                       # See Documentation/i386/boot.txt for
-                                       # assigned ids
-       
- # flags, unused bits must be zero (RFU) bit within loadflags
-loadflags:
-LOADED_HIGH    = 1                     # If set, the kernel is loaded high
-CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
-                                       # heap_end_ptr to tell how much
-                                       # space behind setup.S can be used for
-                                       # heap purposes.
-                                       # Only the loader knows what is free
-
-               .byte   LOADED_HIGH     # Dont force the loader to move 
-                                       # us to 0x90000
-
-setup_move_size: .word  0              # Unused
-
-code32_start:                          # here loaders can put a different
-                                       # start address for 32-bit code.
-               .long   0x100000        # 0x100000 = default for big kernel
-
-ramdisk_image: .long   0               # address of loaded ramdisk image
-                                       # Here the loader puts the 32-bit
-                                       # address where it loaded the image.
-                                       # This only will be read by the kernel.
-
-ramdisk_size:  .long   0               # its size in bytes
-
-bootsect_kludge:
-               .word  0, 0
-
-heap_end_ptr:  .word  0                # (Header version 0x0201 or later)
-                                       # space from here (exclusive) down to
-                                       # end of setup code can be used by setup
-                                       # for local heap purposes.
-
-pad1:          .word 0
-cmd_line_ptr:  .long 0                 # (Header version 0x0202 or later)
-                                       # If nonzero, a 32-bit pointer
-                                       # to the kernel command line.
-                                       # The command line should be
-                                       # located between the start of
-                                       # setup and the end of low
-                                       # memory (0xa0000), or it may
-                                       # get overwritten before it
-                                       # gets read.  If this field is
-                                       # used, there is no longer
-                                       # anything magical about the
-                                       # 0x90000 segment; the setup
-                                       # can be located anywhere in
-                                       # low memory 0x10000 or higher.
-
-ramdisk_max:   .long 0xffffffff        # Load ramdisk as high as
-                                       # absolutely possible
-
-/* ------------------- End of setup header --------------------------- */
-
-LOWSEG = 0x0800                # 0x8000 physical
-
-/*
- * Move ourselves down in memory to reduce the risk of conflicts;
- * the canonicalize CS to match the other segments...
- *
- * The C code uses 32-bit registers to make sure the high part of
- * %esp is zero.
- *
- * The C code expects %cs == %ds == %es == %ss, and %fs == 0.
- */
-start:
-               movw $LOWSEG,%ax
-               movw %ax,%es
-               movzbw setup_sects,%cx
-               inc %cx                 # Add one for the boot sector
-               shlw $7,%cx             # Convert to dwords
-               xorw %si,%si
-               xorw %di,%di
-               movw %si,%fs            # %fs -> zero segment
-               cld
-               rep ; movsl %ds:(%si),%es:(%di)
-               movw %ax,%ds
-               movw %ax,%ss
-               xorl %esp,%esp          # Stack at the top of the segment
-               ljmp $LOWSEG, $startc
-
-startc:
-/*
- * Copy the command line, if there is one
- */
-               xorw %di,%di            # Bottom of our own segment
-               movl cmd_line_ptr, %eax
-               andl %eax,%eax
-               jz endcmd               # No command line?
-               movw %ax,%si
-               shrl $4,%eax            # Convert to a segment address
-               andw $0x000F,%si        # Starting offset
-               movw %ax,%gs
-               movw $496,%cx           # Maximum number of bytes
-copycmd:
-               lodsb %gs:(%si),%al
-               andb %al,%al            # Make sure we're null-terminated
-               jz endcmd
-               stosb %al,%es:(%di)
-               loopw copycmd
-endcmd:
-               xorb %al,%al
-               stosb %al,%es:(%di)
-/*
- * Jump to 32-bit code
- */
-               sti
-               call init32             # Call the 32-bit code
-               # The setup function returns the drive number,
-               # which should be returned in %dl
-               movw %ax,%dx
-
-               # If the 32-bit code returns, we are good to go, and the
-               # new boot sector is already loaded
-               cli
-               movw $0x7c00,%sp
-               xorw %si,%si            # Not a partition BS - SI <- 0
-               movw %si,%ds
-               movw %si,%es
-               movw %si,%fs
-               movw %si,%gs
-               movw %si,%ss
-               ljmp $0,$0x7c00         # Entrypoint at 0000:7C00
-
-               .section ".rodata","a"
-memdisk_version:
-               .ascii "MEMDISK " VERSION " " DATE
-               .ascii "Copyright " FIRSTYEAR "-" COPYYEAR " H. Peter Anvin"
-               .byte 0
-
index 5377120..b6e36f1 100644 (file)
@@ -36,6 +36,7 @@ extern void __attribute__((noreturn)) die(void);
 /* Standard routines */
 #define memcpy(a,b,c) __builtin_memcpy(a,b,c)
 #define memset(a,b,c) __builtin_memset(a,b,c)
+#define strcpy(a,b)   __builtin_strcpy(a,b)
 #define strlen(a)     __builtin_strlen(a)
 
 /* memcpy() but returns a pointer to end of buffer */
similarity index 81%
rename from memdisk/init32.asm
rename to memdisk/memdisk16.asm
index bfbca85..52536ae 100644 (file)
@@ -2,7 +2,7 @@
 ;; $Id$
 ;; -----------------------------------------------------------------------
 ;;   
-;;   Copyright 1994-2003 H. Peter Anvin - All Rights Reserved
+;;   Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
 ;;
 ;;   This program is free software; you can redistribute it and/or modify
 ;;   it under the terms of the GNU General Public License as published by
 ;; -----------------------------------------------------------------------
 
 ;;
-;; init32.asm
-;; 
-;; Routine to trampoline into 32-bit protected memory.  This code is
-;; derived from bcopy32.inc and com32.inc in the main SYSLINUX distribution.
+;; init16.asm
+;;
+;; Routine to initialize and to trampoline into 32-bit
+;; protected memory.  This code is derived from bcopy32.inc and
+;; com32.inc in the main SYSLINUX distribution.
 ;;
 
-%define MY_CS 0x0800
-%define CS_BASE (MY_CS << 4)
+MY_CS          equ 0x0800              ; Segment address to use
+CS_BASE                equ (MY_CS << 4)        ; Corresponding address
 
 ; Low memory bounce buffer
-%define BOUNCE_SEG     (MY_CS+0x1000)
+BOUNCE_SEG     equ (MY_CS+0x1000)
 
 %define DO_WBINVD 0
 
                section .data   align=16
                section .bss    align=16
 
-               global init32
-               
+;; -----------------------------------------------------------------------
+;;  Kernel image header
+;; -----------------------------------------------------------------------
+
+               section .text           ; Must be first in image
+               bits 16
+
+               times 497 db 0          ; Start of header
+setup_sects    db 0
+root_flags     dw 0
+syssize                dw 0
+swap_dev       dw 0
+ram_size       dw 0
+vid_mode       dw 0
+root_dev       dw 0
+boot_flag      dw 0xAA55
+
+_start:                jmp short start
+
+               db "HdrS"               ; Header signature
+               dw 0x0203               ; Header version number
+
+realmode_swtch dw 0, 0                 ; default_switch, SETUPSEG
+start_sys_seg  dw 0x1000               ; obsolete
+version_ptr    dw memdisk_version-0x200        ; version string ptr
+type_of_loader db 0                    ; Filled in by boot loader
+loadflags      db 1                    ; Please load high
+setup_move_size        dw 0                    ; Unused
+code32_start   dd 0x100000             ; 32-bit start address
+ramdisk_image  dd 0                    ; Loaded ramdisk image address
+ramdisk_size   dd 0                    ; Size of loaded ramdisk
+bootsect_kludge        dw 0, 0
+heap_end_ptr   dw 0
+pad1           dw 0
+cmd_line_ptr   dd 0                    ; Command line
+ramdisk_max    dd 0xffffffff           ; Highest allowed ramdisk address
+
+               section .rodata
+memdisk_version:
+               db "MEMDISK ", VERSION, " ", DATE, 0
+
+;; -----------------------------------------------------------------------
+;;  End kernel image header
+;; -----------------------------------------------------------------------
+
+;
+; Move ourselves down into memory to reduce the risk of conflicts;
+; then canonicalize CS to match the other segments.
+;
+               section .text
+               bits 16
+start:
+               mov ax,MY_CS
+               mov es,ax
+               movzx cx,byte [setup_sects]
+               inc cx                  ; Add one for the boot sector
+               shl cx,7                ; Convert to dwords
+               xor si,si
+               xor di,di
+               mov fs,si               ; fs <- 0
+               cld
+               rep movsd
+               mov ds,ax
+               mov ss,ax
+               xor esp,esp             ; Stack at top of 64K segment
+               jmp MY_CS:.next
+.next:
+
+;
+; Copy the command line, if there is one
+;
+copy_cmdline:
+               xor di,di               ; Bottom of our own segment (= "boot sector")
+               mov eax,[cmd_line_ptr]
+               and eax,eax
+               jz .endcmd              ; No command line
+               mov si,ax
+               shr eax,4               ; Convert to segment
+               and si,0x000F           ; Starting offset only
+               mov gs,ax
+               mov cx,496              ; Max number of bytes
+.copycmd:
+               lodsb
+               and al,al
+               jz .endcmd
+               stosb
+               loop .copycmd
+.endcmd:
+               xor al,al
+               stosb
+
+;
+; Now jump to 32-bit code
+;
+               sti
+               call init32
+;
+; When init32 returns, we have been set up, the new boot sector loaded,
+; and we should go and and run the newly loaded boot sector
+;
+; The setup function returns (in AL) the drive number which should be
+; put into DL
+;
+               mov dx,ax
+
+               cli
+               xor esi,esi             ; No partition table involved
+               mov ds,si               ; Make all the segments consistent
+               mov es,si
+               mov fs,si
+               mov gs,si
+               mov ss,si
+               mov esp,0x7C00          ; Good place for SP to start out
+               jmp 0:0x7C00
+
 ;
 ; We enter protected mode, set up a flat 32-bit environment, run rep movsd
 ; and then exit.  IMPORTANT: This code assumes cs == MY_CS.
        dd (%1 & 0xff000000) | (%2 & 0xf0000) | ((%3 & 0xf0ff) << 8) | ((%1 & 0x00ff0000) >> 16)
 %endmacro
        
-               align 4
+               align 8, db 0
 call32_gdt:    dw call32_gdt_size-1    ; Null descriptor - contains GDT
 .adj1:         dd call32_gdt+CS_BASE   ; pointer for LGDT instruction
                dw 0
@@ -75,7 +189,6 @@ call32_gdt_size:     equ $-call32_gdt
 
 err_a20:       db 'ERROR: A20 gate not responding!',13,10,0
        
-               bits 16
                section .bss
                alignb 4
 SavedSSSP      resd 1                  ; Place to save SS:SP
@@ -91,6 +204,7 @@ Target_Seg   dw 20h                  ; Target CS
 A20Type                dw 0                    ; Default = unknown
                
                section .text
+               bits 16
 ;
 ; Routines to enable and disable (yuck) A20.  These routines are gathered
 ; from tips from a couple of sources, including the Linux kernel and
@@ -110,7 +224,7 @@ A20Type             dw 0                    ; Default = unknown
 %define A20_KBC                3               ; A20 through KBC
 %define A20_FAST       4               ; A20 through port 92h
 
-               align 2
+               align 2, db 0
 A20List                dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast
 A20DList       dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast
 a20_adjust_cnt equ ($-A20List)/2
@@ -360,7 +474,7 @@ try_wbinvd:
                alignb 4
 PMESP          resd 1                  ; Protected mode %esp
 
-               section .idt nobits alloc exec write align=4096
+               section .idt nobits align=4096
                alignb 4096
 pm_idt         resb 4096               ; Protected-mode IDT, followed by interrupt stubs
 
index b3bcc9d..d52e11c 100644 (file)
@@ -17,7 +17,6 @@
 #include "version.h"
 #include "memdisk.h"
 
-/* A pointer to this is stored in the header */
 const char memdisk_version[] =
 "MEMDISK " VERSION " " DATE;
 const char copyright[] = 
@@ -369,6 +368,8 @@ struct dosemu_header {
   uint8_t pad[105];
 } __attribute__((packed));
 
+#define FOUR(a,b,c,d) (((a) << 24)|((b) << 16)|((c) << 8)|(d))
+
 const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
 {
   static struct geometry hd_geometry = { 0, 0, 0, 0, 0, 0, 0x80 };
@@ -400,7 +401,8 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
 
   /* Do we have a DOSEMU header? */
   memcpy(&dosemu, (char *)where+hd_geometry.offset, sizeof dosemu);
-  if ( !__builtin_memcmp("DOSEMU", dosemu.magic, 7) ) {
+  if ( ((unsigned long *)dosemu.magic)[0] == FOUR('D','O','S','E') &&
+       (((unsigned long *)dosemu.magic)[1] & 0xffffff) == FOUR('M','U',0,0) ) {
     /* Always a hard disk unless overruled by command-line options */
     hd_geometry.driveno = 0x80;
     hd_geometry.type = 0;
index b7d2fdd..18cf6e0 100644 (file)
@@ -122,6 +122,7 @@ static void *malloc(int size)
 static void free(void *where)
 {
   /* Don't care */
+  (void)where;
 }
 
 static void gzip_mark(void **ptr)