aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErwan Velu <erwanaliasr1@gmail.com>2010-05-11 22:57:47 +0200
committerErwan Velu <erwanaliasr1@gmail.com>2010-05-11 22:57:47 +0200
commitebce0cf25db2a9f0bb4111d7e9ba00b9205e2d6f (patch)
tree03ef602111d4e51495f229a79889409fc4b9fe0a
parentaa1e064d872ea0b14bbbf67277b069b0a2f30d91 (diff)
parent9c2b6b0e10289a6d22792b07257d86d1af2fe005 (diff)
downloadcontrib-ebce0cf25db2a9f0bb4111d7e9ba00b9205e2d6f.tar.gz
contrib-ebce0cf25db2a9f0bb4111d7e9ba00b9205e2d6f.tar.xz
contrib-ebce0cf25db2a9f0bb4111d7e9ba00b9205e2d6f.zip
Merge branch 'master' of git://git.kernel.org/pub/scm/boot/syslinux/syslinux
-rw-r--r--MCONFIG5
-rw-r--r--MCONFIG.embedded16
-rw-r--r--Makefile7
-rw-r--r--NEWS48
-rw-r--r--README2
-rw-r--r--com32/MCONFIG19
-rw-r--r--com32/Makefile3
-rw-r--r--com32/cmenu/adv_menu.tpl4
-rw-r--r--com32/cmenu/complex.c4
-rw-r--r--com32/cmenu/libmenu/menu.c10
-rw-r--r--com32/cmenu/libmenu/menu.h8
-rw-r--r--com32/cmenu/libmenu/passwords.c2
-rw-r--r--com32/gfxboot/.gitignore1
-rw-r--r--com32/gfxboot/Makefile4
-rw-r--r--com32/gfxboot/gfxboot.c240
-rw-r--r--com32/gfxboot/realmode_callback.asm2
-rw-r--r--com32/gplinclude/disk/bootloaders.h2
-rw-r--r--com32/gpllib/cpuid.c6
-rw-r--r--com32/gpllib/disk/ata.c2
-rw-r--r--com32/gpllib/disk/bootloaders.c2
-rw-r--r--com32/gpllib/dmi/dmi_processor.c52
-rw-r--r--com32/hdt/hdt-cli-syslinux.c4
-rw-r--r--com32/hdt/hdt-cli.c6
-rw-r--r--com32/hdt/hdt-cli.h2
-rw-r--r--com32/hdt/hdt-common.c2
-rw-r--r--com32/hdt/hdt-common.h2
-rw-r--r--com32/hdt/hdt-menu-syslinux.c8
-rw-r--r--com32/hdt/hdt-menu.c2
-rw-r--r--com32/hdt/hdt-menu.h2
-rw-r--r--com32/include/com32.h7
-rw-r--r--com32/include/syslinux/config.h2
-rw-r--r--com32/include/syslinux/pxe.h7
-rw-r--r--com32/include/syslinux/video.h4
-rw-r--r--com32/lib/MCONFIG2
-rw-r--r--com32/lib/Makefile13
-rw-r--r--com32/lib/chdir.c4
-rw-r--r--com32/lib/closedir.c1
-rw-r--r--com32/lib/fdopendir.c2
-rw-r--r--com32/lib/libgcc/__moddi3.c2
-rw-r--r--com32/lib/opendir.c1
-rw-r--r--com32/lib/pci/bios.c (renamed from com32/lib/pci/readbios.c)4
-rw-r--r--com32/lib/pci/pci.h3
-rw-r--r--com32/lib/pci/readx.c6
-rw-r--r--com32/lib/pci/writebios.c14
-rw-r--r--com32/lib/pci/writex.c5
-rw-r--r--com32/lib/readdir.c5
-rw-r--r--com32/lib/strcasecmp.c3
-rw-r--r--com32/lib/strcmp.c3
-rw-r--r--com32/lib/strncasecmp.c3
-rw-r--r--com32/lib/strncmp.c3
-rw-r--r--com32/lib/sys/argv.c7
-rw-r--r--com32/lib/sys/colortable.c2
-rw-r--r--com32/lib/sys/entry.S2
-rw-r--r--com32/lib/sys/libansi.c34
-rw-r--r--com32/lib/sys/vesa/background.c61
-rw-r--r--com32/lib/sys/vesa/i915resolution.c795
-rw-r--r--com32/lib/sys/vesa/initvesa.c28
-rw-r--r--com32/lib/sys/vesa/screencpy.c2
-rw-r--r--com32/lib/sys/vesa/video.h2
-rw-r--r--com32/lib/sys/vesaserial_write.c2
-rw-r--r--com32/lib/syslinux/getadv.c2
-rw-r--r--com32/lib/syslinux/load_linux.c3
-rw-r--r--com32/lib/syslinux/pxe_dns.c70
-rw-r--r--com32/lib/syslinux/video/fontquery.c54
-rw-r--r--com32/lib/syslinux/video/forcetext.c42
-rw-r--r--com32/lib/syslinux/video/reportmode.c45
-rw-r--r--com32/lib/zlib/crc32.c2
-rw-r--r--com32/mboot/Makefile2
-rw-r--r--com32/mboot/map.c4
-rw-r--r--com32/mboot/mboot.c26
-rw-r--r--com32/mboot/mboot.h9
-rw-r--r--com32/mboot/solaris.c11
-rw-r--r--com32/mboot/syslinux.c45
-rw-r--r--com32/menu/menu.h1
-rw-r--r--com32/menu/menumain.c25
-rw-r--r--com32/menu/readconfig.c5
-rw-r--r--com32/modules/Makefile3
-rw-r--r--com32/modules/chain.c229
-rw-r--r--com32/modules/cpuid.c60
-rw-r--r--com32/rosh/MCONFIG4
-rw-r--r--com32/rosh/rosh.c8
-rw-r--r--com32/sysdump/Makefile60
-rw-r--r--com32/sysdump/README19
-rw-r--r--com32/sysdump/backend.h54
-rw-r--r--com32/sysdump/be_tftp.c143
-rw-r--r--com32/sysdump/be_ymodem.c175
-rw-r--r--com32/sysdump/cpio.c75
-rw-r--r--com32/sysdump/cpuid.c112
-rw-r--r--com32/sysdump/ctime.c70
-rw-r--r--com32/sysdump/ctime.h8
-rw-r--r--com32/sysdump/data.h2
-rw-r--r--com32/sysdump/dmi.c126
-rw-r--r--com32/sysdump/main.c97
-rw-r--r--com32/sysdump/memmap.c81
-rw-r--r--com32/sysdump/memory.c51
-rw-r--r--com32/sysdump/pci.c70
-rw-r--r--com32/sysdump/serial.c169
-rw-r--r--com32/sysdump/serial.h19
-rw-r--r--com32/sysdump/srecsend.h9
-rw-r--r--com32/sysdump/sysdump.h14
-rw-r--r--com32/sysdump/vesa.c60
-rw-r--r--com32/sysdump/ymodem.txt2108
-rw-r--r--com32/sysdump/zout.c99
-rw-r--r--core/bootsect.inc6
-rw-r--r--core/com32.inc14
-rw-r--r--core/comboot.inc11
-rw-r--r--core/configinit.inc10
-rw-r--r--core/conio.inc1
-rw-r--r--core/cpuinit.inc47
-rw-r--r--core/diskstart.inc7
-rw-r--r--core/idle.inc6
-rw-r--r--core/isolinux.asm4
-rw-r--r--core/kernel.inc2
-rw-r--r--core/layout.inc20
-rw-r--r--core/ldlinux.asm35
-rw-r--r--core/pxe.inc1
-rw-r--r--core/pxelinux.asm346
-rw-r--r--core/runkernel.inc24
-rw-r--r--core/syslinux.ld3
-rw-r--r--core/ui.inc18
-rw-r--r--doc/comboot.txt21
-rw-r--r--doc/memdisk.txt15
-rw-r--r--doc/menu.txt8
-rw-r--r--doc/syslinux.txt17
-rw-r--r--dos/Makefile2
-rw-r--r--dosutil/Makefile14
-rw-r--r--dosutil/copybs.asm (renamed from dos/copybs.asm)0
-rw-r--r--dosutil/eltorito.asm9
-rw-r--r--[-rwxr-xr-x]dosutil/mdiskchk.combin7273 -> 7273 bytes
-rw-r--r--extlinux/Makefile2
-rwxr-xr-xgen-id.sh5
-rw-r--r--gpxe/gpxe.diff73
-rw-r--r--gpxe/pxelinux.gpxe1
-rw-r--r--gpxe/src/Makefile24
-rw-r--r--gpxe/src/Makefile.housekeeping220
-rw-r--r--gpxe/src/README.pixify90
-rw-r--r--gpxe/src/arch/i386/Makefile33
-rw-r--r--gpxe/src/arch/i386/Makefile.pcbios29
-rw-r--r--gpxe/src/arch/i386/core/basemem_packet.c2
-rw-r--r--gpxe/src/arch/i386/core/etherboot.prefix.lds100
-rw-r--r--gpxe/src/arch/i386/core/pic8259.c2
-rw-r--r--gpxe/src/arch/i386/core/prefixudata.lds8
-rw-r--r--gpxe/src/arch/i386/core/prefixzdata.lds8
-rw-r--r--gpxe/src/arch/i386/core/rdtsc_timer.c2
-rw-r--r--gpxe/src/arch/i386/core/realmode.c23
-rw-r--r--gpxe/src/arch/i386/core/relocate.c2
-rw-r--r--gpxe/src/arch/i386/core/setjmp.S2
-rw-r--r--gpxe/src/arch/i386/core/stack.S2
-rw-r--r--gpxe/src/arch/i386/core/stack16.S2
-rw-r--r--gpxe/src/arch/i386/core/start16.lds8
-rw-r--r--gpxe/src/arch/i386/core/start16z.lds65
-rw-r--r--gpxe/src/arch/i386/core/timer2.c2
-rw-r--r--gpxe/src/arch/i386/core/virtaddr.S2
-rw-r--r--gpxe/src/arch/i386/core/x86_io.c2
-rw-r--r--gpxe/src/arch/i386/drivers/net/undi.c4
-rw-r--r--gpxe/src/arch/i386/drivers/net/undiisr.S6
-rw-r--r--gpxe/src/arch/i386/drivers/net/undiload.c7
-rw-r--r--gpxe/src/arch/i386/drivers/net/undinet.c273
-rw-r--r--gpxe/src/arch/i386/drivers/net/undionly.c2
-rw-r--r--gpxe/src/arch/i386/drivers/net/undipreload.c2
-rw-r--r--gpxe/src/arch/i386/drivers/net/undirom.c2
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/basemem.c2
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/bios_console.c2
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/e820mangler.S5
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/fakee820.c2
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/gateA20.c2
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/hidemem.c2
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/memmap.c2
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/pnpbios.c2
-rw-r--r--gpxe/src/arch/i386/hci/commands/pxe_cmd.c33
-rw-r--r--gpxe/src/arch/i386/image/bootsector.c2
-rw-r--r--gpxe/src/arch/i386/image/bzimage.c483
-rw-r--r--gpxe/src/arch/i386/image/com32.c2
-rw-r--r--gpxe/src/arch/i386/image/comboot.c2
-rw-r--r--gpxe/src/arch/i386/image/elfboot.c2
-rw-r--r--gpxe/src/arch/i386/image/eltorito.c2
-rw-r--r--gpxe/src/arch/i386/image/multiboot.c44
-rw-r--r--gpxe/src/arch/i386/image/pxe_image.c18
-rw-r--r--gpxe/src/arch/i386/include/basemem.h2
-rw-r--r--gpxe/src/arch/i386/include/basemem_packet.h2
-rw-r--r--gpxe/src/arch/i386/include/bios.h2
-rw-r--r--gpxe/src/arch/i386/include/biosint.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/byteswap.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/compiler.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/endian.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/errfile.h3
-rw-r--r--gpxe/src/arch/i386/include/bits/io.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/nap.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/smbios.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/stdint.h6
-rw-r--r--gpxe/src/arch/i386/include/bits/timer.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/uaccess.h2
-rw-r--r--gpxe/src/arch/i386/include/bits/umalloc.h2
-rw-r--r--gpxe/src/arch/i386/include/bootsector.h2
-rw-r--r--gpxe/src/arch/i386/include/bzimage.h5
-rw-r--r--gpxe/src/arch/i386/include/callbacks_arch.h243
-rw-r--r--gpxe/src/arch/i386/include/comboot.h2
-rw-r--r--gpxe/src/arch/i386/include/fakee820.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/abft.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/bios_nap.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/bios_smbios.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/bios_timer.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/ibft.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/memtop_umalloc.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/rdtsc_timer.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/sbft.h125
-rw-r--r--gpxe/src/arch/i386/include/gpxe/timer2.h2
-rw-r--r--gpxe/src/arch/i386/include/gpxe/x86_io.h2
-rw-r--r--gpxe/src/arch/i386/include/int13.h2
-rw-r--r--[-rwxr-xr-x]gpxe/src/arch/i386/include/librm.h2
-rw-r--r--gpxe/src/arch/i386/include/limits.h2
-rw-r--r--gpxe/src/arch/i386/include/memsizes.h2
-rw-r--r--gpxe/src/arch/i386/include/multiboot.h2
-rw-r--r--gpxe/src/arch/i386/include/pic8259.h2
-rw-r--r--gpxe/src/arch/i386/include/pnpbios.h2
-rw-r--r--gpxe/src/arch/i386/include/pxe.h3
-rw-r--r--gpxe/src/arch/i386/include/pxe_api.h68
-rw-r--r--gpxe/src/arch/i386/include/pxe_call.h28
-rw-r--r--gpxe/src/arch/i386/include/pxe_types.h2
-rw-r--r--gpxe/src/arch/i386/include/pxeparent.h11
-rw-r--r--gpxe/src/arch/i386/include/realmode.h2
-rw-r--r--gpxe/src/arch/i386/include/registers.h2
-rw-r--r--gpxe/src/arch/i386/include/setjmp.h2
-rw-r--r--gpxe/src/arch/i386/include/undi.h2
-rw-r--r--gpxe/src/arch/i386/include/undiload.h2
-rw-r--r--gpxe/src/arch/i386/include/undinet.h2
-rw-r--r--gpxe/src/arch/i386/include/undipreload.h2
-rw-r--r--gpxe/src/arch/i386/include/undirom.h2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/abft.c2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/aoeboot.c62
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/bios_nap.c2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/bios_smbios.c2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/bios_timer.c2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/biosint.c2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/ib_srpboot.c73
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/ibft.c17
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/int13.c79
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/iscsiboot.c20
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/keepsan.c26
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/memtop_umalloc.c2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/pcibios.c2
-rw-r--r--gpxe/src/arch/i386/interface/pcbios/sbft.c105
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_call.c93
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_entry.S2
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_file.c42
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_loader.c5
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_preboot.c25
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_tftp.c17
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_udp.c2
-rw-r--r--gpxe/src/arch/i386/interface/pxe/pxe_undi.c215
-rw-r--r--gpxe/src/arch/i386/interface/pxeparent/pxeparent.c201
-rw-r--r--gpxe/src/arch/i386/interface/pxeparent/pxeparent_dhcp.c69
-rw-r--r--gpxe/src/arch/i386/interface/syslinux/com32_call.c2
-rw-r--r--gpxe/src/arch/i386/interface/syslinux/com32_wrapper.S2
-rw-r--r--gpxe/src/arch/i386/interface/syslinux/comboot_call.c31
-rw-r--r--gpxe/src/arch/i386/interface/syslinux/comboot_resolv.c2
-rw-r--r--gpxe/src/arch/i386/prefix/bImageprefix.S611
-rw-r--r--gpxe/src/arch/i386/prefix/bootpart.S2
-rw-r--r--gpxe/src/arch/i386/prefix/comprefix.S46
-rw-r--r--gpxe/src/arch/i386/prefix/dskprefix.S6
-rw-r--r--gpxe/src/arch/i386/prefix/elf_dprefix.S94
-rw-r--r--gpxe/src/arch/i386/prefix/elfprefix.S94
-rwxr-xr-xgpxe/src/arch/i386/prefix/exeprefix.S41
-rw-r--r--gpxe/src/arch/i386/prefix/hdprefix.S6
-rw-r--r--gpxe/src/arch/i386/prefix/hromprefix.S12
-rw-r--r--gpxe/src/arch/i386/prefix/kkpxeprefix.S5
-rw-r--r--gpxe/src/arch/i386/prefix/kpxeprefix.S2
-rw-r--r--gpxe/src/arch/i386/prefix/libprefix.S2
-rw-r--r--gpxe/src/arch/i386/prefix/lkrnprefix.S6
-rw-r--r--gpxe/src/arch/i386/prefix/lmelf_dprefix.S161
-rw-r--r--gpxe/src/arch/i386/prefix/lmelf_prefix.S161
-rw-r--r--gpxe/src/arch/i386/prefix/nbiprefix.S8
-rw-r--r--gpxe/src/arch/i386/prefix/pxeprefix.S100
-rw-r--r--gpxe/src/arch/i386/prefix/romprefix.S480
-rw-r--r--gpxe/src/arch/i386/prefix/undiloader.S49
-rw-r--r--gpxe/src/arch/i386/prefix/unnrv2b.S2
-rw-r--r--gpxe/src/arch/i386/prefix/unnrv2b16.S9
-rw-r--r--gpxe/src/arch/i386/prefix/xromprefix.S9
-rw-r--r--gpxe/src/arch/i386/scripts/i386-kir.lds1
-rw-r--r--gpxe/src/arch/i386/scripts/i386.lds11
-rw-r--r--gpxe/src/arch/i386/transitions/libkir.S2
-rw-r--r--[-rwxr-xr-x]gpxe/src/arch/i386/transitions/librm.S2
-rw-r--r--[-rwxr-xr-x]gpxe/src/arch/i386/transitions/librm_mgmt.c2
-rw-r--r--gpxe/src/arch/x86/Makefile2
-rw-r--r--gpxe/src/arch/x86/core/pcidirect.c2
-rw-r--r--gpxe/src/arch/x86/core/x86_string.c2
-rw-r--r--gpxe/src/arch/x86/include/bits/pci_io.h2
-rw-r--r--gpxe/src/arch/x86/include/bits/string.h2
-rw-r--r--gpxe/src/arch/x86/include/gpxe/efi/efix86_nap.h2
-rw-r--r--gpxe/src/arch/x86/include/gpxe/pcibios.h2
-rw-r--r--gpxe/src/arch/x86/include/gpxe/pcidirect.h2
-rw-r--r--gpxe/src/arch/x86/interface/efi/efix86_nap.c2
-rw-r--r--gpxe/src/arch/x86/prefix/efidrvprefix.c2
-rw-r--r--gpxe/src/arch/x86/prefix/efiprefix.c2
-rw-r--r--gpxe/src/arch/x86/scripts/efi.lds1
-rw-r--r--gpxe/src/arch/x86_64/include/bits/stdint.h2
-rw-r--r--gpxe/src/config/config.c (renamed from gpxe/src/core/config.c)50
-rw-r--r--gpxe/src/config/config_net80211.c50
-rw-r--r--gpxe/src/config/config_romprefix.c24
-rw-r--r--gpxe/src/config/console.h2
-rw-r--r--gpxe/src/config/defaults.h2
-rw-r--r--gpxe/src/config/defaults/pcbios.h6
-rw-r--r--gpxe/src/config/general.h33
-rw-r--r--gpxe/src/config/ioapi.h2
-rw-r--r--gpxe/src/config/nap.h2
-rw-r--r--gpxe/src/config/serial.h9
-rw-r--r--gpxe/src/config/timer.h2
-rw-r--r--gpxe/src/config/umalloc.h2
-rw-r--r--gpxe/src/core/acpi.c2
-rw-r--r--gpxe/src/core/ansiesc.c2
-rw-r--r--gpxe/src/core/asprintf.c2
-rw-r--r--gpxe/src/core/base64.c2
-rw-r--r--gpxe/src/core/basename.c2
-rw-r--r--gpxe/src/core/bitmap.c2
-rw-r--r--gpxe/src/core/bitops.c2
-rw-r--r--gpxe/src/core/console.c11
-rw-r--r--gpxe/src/core/cpio.c2
-rw-r--r--gpxe/src/core/ctype.c48
-rw-r--r--gpxe/src/core/cwuri.c2
-rw-r--r--gpxe/src/core/debug.c3
-rw-r--r--gpxe/src/core/device.c9
-rw-r--r--gpxe/src/core/downloader.c27
-rw-r--r--gpxe/src/core/exec.c14
-rw-r--r--gpxe/src/core/filter.c2
-rw-r--r--gpxe/src/core/gdbstub.c17
-rw-r--r--gpxe/src/core/getkey.c2
-rw-r--r--gpxe/src/core/getopt.c2
-rw-r--r--gpxe/src/core/image.c10
-rw-r--r--gpxe/src/core/init.c25
-rw-r--r--gpxe/src/core/interface.c2
-rw-r--r--gpxe/src/core/iobuf.c2
-rw-r--r--gpxe/src/core/job.c10
-rw-r--r--gpxe/src/core/linebuf.c2
-rw-r--r--gpxe/src/core/main.c9
-rw-r--r--gpxe/src/core/malloc.c6
-rw-r--r--gpxe/src/core/misc.c17
-rw-r--r--gpxe/src/core/monojob.c2
-rw-r--r--gpxe/src/core/nvo.c2
-rw-r--r--gpxe/src/core/open.c41
-rw-r--r--gpxe/src/core/posix_io.c4
-rw-r--r--gpxe/src/core/process.c24
-rw-r--r--gpxe/src/core/random.c2
-rw-r--r--gpxe/src/core/refcnt.c2
-rw-r--r--gpxe/src/core/resolv.c53
-rw-r--r--gpxe/src/core/serial.c2
-rw-r--r--gpxe/src/core/settings.c500
-rw-r--r--gpxe/src/core/string.c2
-rw-r--r--gpxe/src/core/timer.c2
-rw-r--r--gpxe/src/core/uri.c165
-rw-r--r--gpxe/src/core/uuid.c2
-rw-r--r--gpxe/src/core/vsprintf.c2
-rw-r--r--gpxe/src/core/xfer.c5
-rw-r--r--gpxe/src/crypto/aes_wrap.c123
-rw-r--r--gpxe/src/crypto/arc4.c131
-rw-r--r--gpxe/src/crypto/asn1.c2
-rw-r--r--gpxe/src/crypto/axtls_aes.c15
-rw-r--r--gpxe/src/crypto/cbc.c2
-rw-r--r--gpxe/src/crypto/chap.c2
-rw-r--r--gpxe/src/crypto/crandom.c55
-rw-r--r--gpxe/src/crypto/crc32.c54
-rw-r--r--gpxe/src/crypto/crypto_null.c2
-rw-r--r--gpxe/src/crypto/hmac.c2
-rw-r--r--gpxe/src/crypto/md5.c14
-rw-r--r--gpxe/src/crypto/sha1extra.c165
-rw-r--r--gpxe/src/crypto/x509.c2
-rw-r--r--gpxe/src/doc/pxe_extensions33
-rw-r--r--gpxe/src/doxygen.cfg434
-rw-r--r--gpxe/src/drivers/bitbash/bitbash.c2
-rw-r--r--gpxe/src/drivers/bitbash/i2c_bit.c2
-rw-r--r--gpxe/src/drivers/bitbash/spi_bit.c53
-rw-r--r--gpxe/src/drivers/block/ata.c27
-rw-r--r--gpxe/src/drivers/block/ramdisk.c2
-rw-r--r--gpxe/src/drivers/block/scsi.c93
-rw-r--r--gpxe/src/drivers/block/srp.c523
-rw-r--r--gpxe/src/drivers/bus/eisa.c7
-rw-r--r--gpxe/src/drivers/bus/isa.c9
-rw-r--r--gpxe/src/drivers/bus/isapnp.c9
-rw-r--r--gpxe/src/drivers/bus/mca.c9
-rw-r--r--gpxe/src/drivers/bus/pci.c9
-rw-r--r--gpxe/src/drivers/bus/pcibackup.c90
-rw-r--r--gpxe/src/drivers/bus/pciextra.c7
-rw-r--r--gpxe/src/drivers/infiniband/MT25218_PRM.h2
-rw-r--r--gpxe/src/drivers/infiniband/MT25408_PRM.h8
-rw-r--r--gpxe/src/drivers/infiniband/arbel.c18
-rw-r--r--gpxe/src/drivers/infiniband/arbel.h2
-rw-r--r--gpxe/src/drivers/infiniband/hermon.c702
-rw-r--r--gpxe/src/drivers/infiniband/hermon.h91
-rw-r--r--gpxe/src/drivers/infiniband/ib_sma.c553
-rw-r--r--gpxe/src/drivers/infiniband/linda.c99
-rw-r--r--gpxe/src/drivers/infiniband/linda.h5
-rw-r--r--gpxe/src/drivers/infiniband/linda_fw.c2
-rw-r--r--gpxe/src/drivers/infiniband/mlx_bitops.h14
-rw-r--r--gpxe/src/drivers/infiniband/qib_7220_regs.h11
-rwxr-xr-x[-rw-r--r--]gpxe/src/drivers/infiniband/qib_genbits.pl29
-rw-r--r--gpxe/src/drivers/net/3c509.c2
-rw-r--r--gpxe/src/drivers/net/3c509.h2
-rw-r--r--gpxe/src/drivers/net/3c515.c1
-rw-r--r--gpxe/src/drivers/net/3c529.c2
-rw-r--r--gpxe/src/drivers/net/3c595.c30
-rw-r--r--gpxe/src/drivers/net/3c595.h2
-rw-r--r--gpxe/src/drivers/net/3c5x9.c2
-rw-r--r--gpxe/src/drivers/net/3c90x.c1837
-rw-r--r--gpxe/src/drivers/net/3c90x.h302
-rw-r--r--gpxe/src/drivers/net/3c90x.txt307
-rw-r--r--gpxe/src/drivers/net/amd8111e.c4
-rw-r--r--gpxe/src/drivers/net/amd8111e.h2
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k.c1700
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k.h1279
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_attach.c340
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_caps.c154
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_desc.c544
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_dma.c631
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_eeprom.c1760
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_gpio.c122
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_initvals.c1560
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_pcu.c534
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_phy.c2586
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_qcu.c394
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_reset.c1176
-rw-r--r--gpxe/src/drivers/net/ath5k/ath5k_rfkill.c107
-rw-r--r--gpxe/src/drivers/net/ath5k/base.h145
-rw-r--r--gpxe/src/drivers/net/ath5k/desc.h332
-rw-r--r--gpxe/src/drivers/net/ath5k/eeprom.h451
-rw-r--r--gpxe/src/drivers/net/ath5k/reg.h2589
-rw-r--r--gpxe/src/drivers/net/ath5k/rfbuffer.h1181
-rw-r--r--gpxe/src/drivers/net/ath5k/rfgain.h516
-rw-r--r--gpxe/src/drivers/net/atl1e.c1758
-rw-r--r--gpxe/src/drivers/net/atl1e.h1031
-rw-r--r--gpxe/src/drivers/net/b44.c20
-rw-r--r--gpxe/src/drivers/net/b44.h3
-rw-r--r--gpxe/src/drivers/net/bnx2.c10
-rw-r--r--gpxe/src/drivers/net/bnx2.h108
-rw-r--r--gpxe/src/drivers/net/cs89x0.c2
-rw-r--r--gpxe/src/drivers/net/cs89x0.h2
-rw-r--r--gpxe/src/drivers/net/davicom.c10
-rw-r--r--gpxe/src/drivers/net/depca.c2
-rw-r--r--gpxe/src/drivers/net/dmfe.c10
-rw-r--r--gpxe/src/drivers/net/e1000/e1000.c392
-rw-r--r--gpxe/src/drivers/net/e1000/e1000.h2
-rw-r--r--gpxe/src/drivers/net/e1000/e1000_hw.c156
-rw-r--r--gpxe/src/drivers/net/e1000/e1000_hw.h20
-rw-r--r--gpxe/src/drivers/net/e1000/e1000_osdep.h1
-rw-r--r--gpxe/src/drivers/net/eepro.c2
-rw-r--r--gpxe/src/drivers/net/eepro100.c1692
-rw-r--r--gpxe/src/drivers/net/eepro100.h206
-rw-r--r--gpxe/src/drivers/net/epic100.c6
-rw-r--r--gpxe/src/drivers/net/epic100.h2
-rw-r--r--gpxe/src/drivers/net/etherfabric.c92
-rw-r--r--gpxe/src/drivers/net/etherfabric.h2
-rw-r--r--gpxe/src/drivers/net/etherfabric_nic.h3
-rw-r--r--gpxe/src/drivers/net/forcedeth.c102
-rw-r--r--gpxe/src/drivers/net/hfa384x.h2
-rw-r--r--gpxe/src/drivers/net/ipoib.c878
-rw-r--r--gpxe/src/drivers/net/legacy.c6
-rw-r--r--gpxe/src/drivers/net/mtd80x.c74
-rw-r--r--gpxe/src/drivers/net/mtnic.c13
-rw-r--r--gpxe/src/drivers/net/mtnic.h3
-rw-r--r--gpxe/src/drivers/net/myri10ge.c1041
-rw-r--r--gpxe/src/drivers/net/myri10ge_mcp.h514
-rw-r--r--gpxe/src/drivers/net/natsemi.c8
-rw-r--r--gpxe/src/drivers/net/natsemi.h2
-rw-r--r--gpxe/src/drivers/net/ne2k_isa.c2
-rw-r--r--[-rwxr-xr-x]gpxe/src/drivers/net/ns83820.c4
-rw-r--r--gpxe/src/drivers/net/ns8390.c24
-rw-r--r--gpxe/src/drivers/net/ns8390.h2
-rw-r--r--gpxe/src/drivers/net/p80211hdr.h2
-rw-r--r--gpxe/src/drivers/net/pcnet32.c20
-rw-r--r--gpxe/src/drivers/net/phantom/nx_bitops.h2
-rw-r--r--gpxe/src/drivers/net/phantom/nxhal_nic_interface.h2
-rw-r--r--gpxe/src/drivers/net/phantom/phantom.c22
-rw-r--r--gpxe/src/drivers/net/phantom/phantom.h2
-rw-r--r--gpxe/src/drivers/net/phantom/phantom_hw.h2
-rw-r--r--gpxe/src/drivers/net/pnic.c6
-rw-r--r--gpxe/src/drivers/net/pnic_api.h2
-rw-r--r--gpxe/src/drivers/net/prism2.c2
-rw-r--r--gpxe/src/drivers/net/prism2_pci.c8
-rw-r--r--gpxe/src/drivers/net/prism2_plx.c24
-rw-r--r--gpxe/src/drivers/net/r8169.c27
-rw-r--r--gpxe/src/drivers/net/r8169.h83
-rw-r--r--gpxe/src/drivers/net/rtl8139.c63
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl8180.c17
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl8180_grf5101.c186
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl8180_max2820.c158
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl8180_sa2400.c217
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl8185.c14
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl8185_rtl8225.c804
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl818x.c855
-rw-r--r--gpxe/src/drivers/net/rtl818x/rtl818x.h359
-rw-r--r--gpxe/src/drivers/net/sis190.c1179
-rw-r--r--gpxe/src/drivers/net/sis190.h311
-rw-r--r--gpxe/src/drivers/net/sis900.c12
-rw-r--r--gpxe/src/drivers/net/sis900.h2
-rwxr-xr-xgpxe/src/drivers/net/skge.c2472
-rwxr-xr-xgpxe/src/drivers/net/skge.h2623
-rw-r--r--gpxe/src/drivers/net/sky2.c2399
-rw-r--r--gpxe/src/drivers/net/sky2.h2176
-rw-r--r--gpxe/src/drivers/net/smc9000.c3
-rw-r--r--gpxe/src/drivers/net/smc9000.h11
-rw-r--r--gpxe/src/drivers/net/sundance.c15
-rw-r--r--gpxe/src/drivers/net/tg3.c67
-rw-r--r--gpxe/src/drivers/net/tg3.h109
-rw-r--r--gpxe/src/drivers/net/tlan.c125
-rw-r--r--gpxe/src/drivers/net/tlan.h37
-rw-r--r--gpxe/src/drivers/net/tulip.c74
-rw-r--r--gpxe/src/drivers/net/via-rhine.c10
-rw-r--r--gpxe/src/drivers/net/via-velocity.c2
-rw-r--r--gpxe/src/drivers/net/virtio-net.c2
-rw-r--r--gpxe/src/drivers/net/w89c840.c6
-rw-r--r--gpxe/src/drivers/net/wlan_compat.h2
-rw-r--r--gpxe/src/drivers/nvs/nvs.c2
-rw-r--r--gpxe/src/drivers/nvs/spi.c2
-rw-r--r--gpxe/src/drivers/nvs/threewire.c55
-rw-r--r--gpxe/src/hci/commands/autoboot_cmd.c2
-rw-r--r--gpxe/src/hci/commands/config_cmd.c2
-rw-r--r--gpxe/src/hci/commands/dhcp_cmd.c2
-rw-r--r--gpxe/src/hci/commands/digest_cmd.c120
-rw-r--r--gpxe/src/hci/commands/ifmgmt_cmd.c21
-rw-r--r--gpxe/src/hci/commands/image_cmd.c25
-rw-r--r--gpxe/src/hci/commands/iwmgmt_cmd.c69
-rw-r--r--gpxe/src/hci/commands/login_cmd.c2
-rw-r--r--gpxe/src/hci/commands/nvo_cmd.c2
-rw-r--r--gpxe/src/hci/commands/route_cmd.c2
-rw-r--r--gpxe/src/hci/commands/sanboot_cmd.c2
-rw-r--r--gpxe/src/hci/commands/time_cmd.c84
-rw-r--r--gpxe/src/hci/editstring.c2
-rw-r--r--gpxe/src/hci/mucurses/ansi_screen.c2
-rw-r--r--gpxe/src/hci/mucurses/clear.c2
-rw-r--r--gpxe/src/hci/mucurses/colour.c2
-rw-r--r--gpxe/src/hci/mucurses/cursor.h2
-rw-r--r--gpxe/src/hci/mucurses/mucurses.c2
-rw-r--r--gpxe/src/hci/mucurses/mucurses.h2
-rw-r--r--gpxe/src/hci/mucurses/print.c2
-rw-r--r--gpxe/src/hci/mucurses/widgets/editbox.c2
-rw-r--r--gpxe/src/hci/mucurses/winattrs.c2
-rw-r--r--gpxe/src/hci/mucurses/wininit.c2
-rw-r--r--gpxe/src/hci/readline.c2
-rw-r--r--gpxe/src/hci/shell.c9
-rw-r--r--gpxe/src/hci/shell_banner.c5
-rw-r--r--gpxe/src/hci/strerror.c19
-rw-r--r--gpxe/src/hci/tui/login_ui.c2
-rw-r--r--gpxe/src/hci/tui/settings_ui.c12
-rw-r--r--gpxe/src/hci/wireless_errors.c118
-rw-r--r--gpxe/src/image/efi_image.c2
-rw-r--r--gpxe/src/image/elf.c57
-rw-r--r--gpxe/src/image/embedded.c2
-rw-r--r--gpxe/src/image/script.c10
-rw-r--r--gpxe/src/image/segment.c13
-rw-r--r--gpxe/src/include/assert.h2
-rw-r--r--gpxe/src/include/byteswap.h2
-rw-r--r--gpxe/src/include/compiler.h345
-rw-r--r--gpxe/src/include/console.h7
-rw-r--r--gpxe/src/include/ctype.h4
-rw-r--r--gpxe/src/include/curses.h2
-rw-r--r--gpxe/src/include/debug.h28
-rw-r--r--gpxe/src/include/dhcp.h12
-rw-r--r--gpxe/src/include/elf.h2
-rw-r--r--gpxe/src/include/endian.h2
-rw-r--r--gpxe/src/include/errno.h2
-rw-r--r--gpxe/src/include/etherboot.h2
-rw-r--r--gpxe/src/include/getopt.h2
-rw-r--r--gpxe/src/include/gpxe/acpi.h2
-rw-r--r--gpxe/src/include/gpxe/aes.h22
-rw-r--r--gpxe/src/include/gpxe/ansiesc.h2
-rw-r--r--gpxe/src/include/gpxe/aoe.h2
-rw-r--r--gpxe/src/include/gpxe/api.h2
-rw-r--r--gpxe/src/include/gpxe/arc4.h22
-rw-r--r--gpxe/src/include/gpxe/arp.h9
-rw-r--r--gpxe/src/include/gpxe/asn1.h2
-rw-r--r--gpxe/src/include/gpxe/ata.h4
-rw-r--r--gpxe/src/include/gpxe/base64.h2
-rw-r--r--gpxe/src/include/gpxe/bitbash.h2
-rw-r--r--gpxe/src/include/gpxe/bitmap.h2
-rw-r--r--gpxe/src/include/gpxe/bitops.h2
-rw-r--r--gpxe/src/include/gpxe/blockdev.h2
-rw-r--r--gpxe/src/include/gpxe/cbc.h2
-rw-r--r--gpxe/src/include/gpxe/chap.h2
-rw-r--r--gpxe/src/include/gpxe/command.h6
-rw-r--r--gpxe/src/include/gpxe/cpio.h2
-rw-r--r--gpxe/src/include/gpxe/crc32.h10
-rw-r--r--gpxe/src/include/gpxe/crypto.h8
-rw-r--r--gpxe/src/include/gpxe/device.h7
-rw-r--r--gpxe/src/include/gpxe/dhcp.h23
-rw-r--r--gpxe/src/include/gpxe/dhcpopts.h2
-rw-r--r--gpxe/src/include/gpxe/dhcppkt.h2
-rw-r--r--gpxe/src/include/gpxe/dns.h2
-rw-r--r--gpxe/src/include/gpxe/downloader.h2
-rw-r--r--gpxe/src/include/gpxe/eapol.h112
-rw-r--r--gpxe/src/include/gpxe/editbox.h2
-rw-r--r--gpxe/src/include/gpxe/editstring.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi.h21
-rw-r--r--gpxe/src/include/gpxe/efi/efi_io.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_pci.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_smbios.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_timer.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_uaccess.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_umalloc.h2
-rw-r--r--gpxe/src/include/gpxe/eisa.h7
-rw-r--r--gpxe/src/include/gpxe/elf.h2
-rw-r--r--gpxe/src/include/gpxe/errfile.h29
-rw-r--r--gpxe/src/include/gpxe/errortab.h6
-rw-r--r--gpxe/src/include/gpxe/ethernet.h28
-rw-r--r--gpxe/src/include/gpxe/fakedhcp.h2
-rw-r--r--gpxe/src/include/gpxe/features.h14
-rw-r--r--gpxe/src/include/gpxe/filter.h2
-rw-r--r--gpxe/src/include/gpxe/ftp.h2
-rw-r--r--gpxe/src/include/gpxe/gdbserial.h2
-rw-r--r--gpxe/src/include/gpxe/gdbstub.h6
-rw-r--r--gpxe/src/include/gpxe/gdbudp.h2
-rw-r--r--gpxe/src/include/gpxe/hidemem.h2
-rw-r--r--gpxe/src/include/gpxe/hmac.h2
-rw-r--r--gpxe/src/include/gpxe/http.h2
-rw-r--r--gpxe/src/include/gpxe/i2c.h2
-rw-r--r--gpxe/src/include/gpxe/ib_cm.h72
-rw-r--r--gpxe/src/include/gpxe/ib_cmrc.h20
-rw-r--r--gpxe/src/include/gpxe/ib_mad.h205
-rw-r--r--gpxe/src/include/gpxe/ib_mcast.h48
-rw-r--r--gpxe/src/include/gpxe/ib_mi.h135
-rw-r--r--gpxe/src/include/gpxe/ib_packet.h14
-rw-r--r--gpxe/src/include/gpxe/ib_pathrec.h76
-rw-r--r--gpxe/src/include/gpxe/ib_sma.h59
-rw-r--r--gpxe/src/include/gpxe/ib_smc.h2
-rw-r--r--gpxe/src/include/gpxe/ib_srp.h79
-rw-r--r--gpxe/src/include/gpxe/icmp.h2
-rw-r--r--gpxe/src/include/gpxe/icmp6.h2
-rw-r--r--gpxe/src/include/gpxe/ieee80211.h1160
-rw-r--r--gpxe/src/include/gpxe/if_arp.h2
-rw-r--r--gpxe/src/include/gpxe/if_ether.h3
-rw-r--r--gpxe/src/include/gpxe/image.h8
-rw-r--r--gpxe/src/include/gpxe/in.h3
-rw-r--r--gpxe/src/include/gpxe/infiniband.h218
-rw-r--r--gpxe/src/include/gpxe/init.h13
-rw-r--r--gpxe/src/include/gpxe/interface.h2
-rw-r--r--gpxe/src/include/gpxe/io.h2
-rw-r--r--gpxe/src/include/gpxe/iobuf.h2
-rw-r--r--gpxe/src/include/gpxe/ip.h2
-rw-r--r--gpxe/src/include/gpxe/ip6.h2
-rw-r--r--gpxe/src/include/gpxe/ipoib.h31
-rw-r--r--gpxe/src/include/gpxe/isa.h7
-rw-r--r--gpxe/src/include/gpxe/isa_ids.h2
-rw-r--r--gpxe/src/include/gpxe/isapnp.h7
-rw-r--r--gpxe/src/include/gpxe/iscsi.h17
-rw-r--r--gpxe/src/include/gpxe/job.h4
-rw-r--r--gpxe/src/include/gpxe/keys.h2
-rw-r--r--gpxe/src/include/gpxe/linebuf.h2
-rw-r--r--gpxe/src/include/gpxe/linux_compat.h2
-rw-r--r--gpxe/src/include/gpxe/list.h2
-rw-r--r--gpxe/src/include/gpxe/login_ui.h2
-rw-r--r--gpxe/src/include/gpxe/malloc.h2
-rw-r--r--gpxe/src/include/gpxe/mca.h7
-rw-r--r--gpxe/src/include/gpxe/md5.h2
-rw-r--r--gpxe/src/include/gpxe/memmap.h2
-rw-r--r--gpxe/src/include/gpxe/monojob.h2
-rw-r--r--gpxe/src/include/gpxe/nap.h2
-rw-r--r--gpxe/src/include/gpxe/net80211.h1186
-rw-r--r--gpxe/src/include/gpxe/netdevice.h135
-rw-r--r--gpxe/src/include/gpxe/null_nap.h2
-rw-r--r--gpxe/src/include/gpxe/nvo.h2
-rw-r--r--gpxe/src/include/gpxe/nvs.h2
-rw-r--r--gpxe/src/include/gpxe/open.h14
-rw-r--r--gpxe/src/include/gpxe/pci.h52
-rw-r--r--gpxe/src/include/gpxe/pci_ids.h3
-rw-r--r--gpxe/src/include/gpxe/pci_io.h2
-rw-r--r--gpxe/src/include/gpxe/pcibackup.h33
-rw-r--r--gpxe/src/include/gpxe/posix_io.h2
-rw-r--r--gpxe/src/include/gpxe/process.h9
-rw-r--r--gpxe/src/include/gpxe/profile.h2
-rw-r--r--gpxe/src/include/gpxe/ramdisk.h2
-rw-r--r--gpxe/src/include/gpxe/rarp.h2
-rw-r--r--gpxe/src/include/gpxe/rc80211.h19
-rw-r--r--gpxe/src/include/gpxe/refcnt.h2
-rw-r--r--gpxe/src/include/gpxe/resolv.h8
-rw-r--r--gpxe/src/include/gpxe/retry.h2
-rw-r--r--gpxe/src/include/gpxe/rotate.h2
-rw-r--r--gpxe/src/include/gpxe/rsa.h2
-rw-r--r--gpxe/src/include/gpxe/sanboot.h10
-rw-r--r--gpxe/src/include/gpxe/scsi.h31
-rw-r--r--gpxe/src/include/gpxe/sec80211.h83
-rw-r--r--gpxe/src/include/gpxe/segment.h2
-rw-r--r--gpxe/src/include/gpxe/serial.h2
-rw-r--r--gpxe/src/include/gpxe/settings.h64
-rw-r--r--gpxe/src/include/gpxe/settings_ui.h2
-rw-r--r--gpxe/src/include/gpxe/sha1.h11
-rw-r--r--gpxe/src/include/gpxe/shell.h2
-rw-r--r--gpxe/src/include/gpxe/shell_banner.h2
-rw-r--r--gpxe/src/include/gpxe/smbios.h21
-rw-r--r--gpxe/src/include/gpxe/socket.h2
-rw-r--r--gpxe/src/include/gpxe/spi.h10
-rw-r--r--gpxe/src/include/gpxe/spi_bit.h2
-rw-r--r--gpxe/src/include/gpxe/srp.h868
-rw-r--r--gpxe/src/include/gpxe/tables.h263
-rw-r--r--gpxe/src/include/gpxe/tcp.h16
-rw-r--r--gpxe/src/include/gpxe/tcpip.h15
-rw-r--r--gpxe/src/include/gpxe/tftp.h2
-rw-r--r--gpxe/src/include/gpxe/threewire.h16
-rw-r--r--gpxe/src/include/gpxe/timer.h2
-rw-r--r--gpxe/src/include/gpxe/tls.h2
-rw-r--r--gpxe/src/include/gpxe/uaccess.h2
-rw-r--r--gpxe/src/include/gpxe/udp.h2
-rw-r--r--gpxe/src/include/gpxe/umalloc.h2
-rw-r--r--gpxe/src/include/gpxe/uri.h46
-rw-r--r--gpxe/src/include/gpxe/uuid.h2
-rw-r--r--gpxe/src/include/gpxe/vsprintf.h2
-rw-r--r--gpxe/src/include/gpxe/wpa.h503
-rw-r--r--gpxe/src/include/gpxe/x509.h2
-rw-r--r--gpxe/src/include/gpxe/xfer.h2
-rw-r--r--gpxe/src/include/hci/ifmgmt_cmd.h30
-rw-r--r--gpxe/src/include/igmp.h42
-rw-r--r--gpxe/src/include/lib.h42
-rw-r--r--gpxe/src/include/libgen.h2
-rw-r--r--gpxe/src/include/little_bswap.h2
-rw-r--r--gpxe/src/include/mii.h122
-rw-r--r--gpxe/src/include/nfs.h63
-rw-r--r--gpxe/src/include/nic.h4
-rw-r--r--gpxe/src/include/nmb.h22
-rw-r--r--gpxe/src/include/readline/readline.h2
-rw-r--r--gpxe/src/include/stdarg.h2
-rw-r--r--gpxe/src/include/stddef.h2
-rw-r--r--gpxe/src/include/stdint.h12
-rw-r--r--gpxe/src/include/stdio.h2
-rw-r--r--gpxe/src/include/stdlib.h2
-rw-r--r--gpxe/src/include/string.h2
-rw-r--r--gpxe/src/include/strings.h2
-rw-r--r--gpxe/src/include/unistd.h2
-rw-r--r--gpxe/src/include/usr/autoboot.h6
-rw-r--r--gpxe/src/include/usr/dhcpmgmt.h2
-rw-r--r--gpxe/src/include/usr/ifmgmt.h2
-rw-r--r--gpxe/src/include/usr/imgmgmt.h2
-rw-r--r--gpxe/src/include/usr/iwmgmt.h17
-rw-r--r--gpxe/src/include/usr/route.h2
-rw-r--r--gpxe/src/interface/efi/efi_console.c2
-rw-r--r--gpxe/src/interface/efi/efi_init.c18
-rw-r--r--gpxe/src/interface/efi/efi_io.c2
-rw-r--r--gpxe/src/interface/efi/efi_pci.c2
-rw-r--r--gpxe/src/interface/efi/efi_smbios.c2
-rw-r--r--gpxe/src/interface/efi/efi_snp.c21
-rw-r--r--gpxe/src/interface/efi/efi_strerror.c2
-rw-r--r--gpxe/src/interface/efi/efi_timer.c2
-rw-r--r--gpxe/src/interface/efi/efi_uaccess.c2
-rw-r--r--gpxe/src/interface/efi/efi_umalloc.c2
-rw-r--r--gpxe/src/interface/smbios/smbios.c2
-rw-r--r--gpxe/src/interface/smbios/smbios_settings.c27
-rw-r--r--gpxe/src/libgcc/icc.c8
-rw-r--r--gpxe/src/net/80211/net80211.c2829
-rw-r--r--gpxe/src/net/80211/rc80211.c371
-rw-r--r--gpxe/src/net/80211/sec80211.c503
-rw-r--r--gpxe/src/net/80211/wep.c303
-rw-r--r--gpxe/src/net/80211/wpa.c973
-rw-r--r--gpxe/src/net/80211/wpa_ccmp.c528
-rw-r--r--gpxe/src/net/80211/wpa_psk.c125
-rw-r--r--gpxe/src/net/80211/wpa_tkip.c586
-rw-r--r--gpxe/src/net/aoe.c15
-rw-r--r--gpxe/src/net/arp.c13
-rw-r--r--gpxe/src/net/cachedhcp.c76
-rw-r--r--gpxe/src/net/dhcpopts.c21
-rw-r--r--gpxe/src/net/dhcppkt.c14
-rw-r--r--gpxe/src/net/eapol.c85
-rw-r--r--gpxe/src/net/ethernet.c56
-rw-r--r--gpxe/src/net/fakedhcp.c2
-rw-r--r--gpxe/src/net/icmp.c2
-rw-r--r--gpxe/src/net/infiniband.c405
-rw-r--r--gpxe/src/net/infiniband/ib_cm.c413
-rw-r--r--gpxe/src/net/infiniband/ib_cmrc.c436
-rw-r--r--gpxe/src/net/infiniband/ib_mcast.c218
-rw-r--r--gpxe/src/net/infiniband/ib_mi.c406
-rw-r--r--gpxe/src/net/infiniband/ib_packet.c (renamed from gpxe/src/drivers/infiniband/ib_packet.c)36
-rw-r--r--gpxe/src/net/infiniband/ib_pathrec.c296
-rw-r--r--gpxe/src/net/infiniband/ib_sma.c369
-rw-r--r--gpxe/src/net/infiniband/ib_smc.c (renamed from gpxe/src/drivers/infiniband/ib_smc.c)31
-rw-r--r--gpxe/src/net/infiniband/ib_srp.c406
-rw-r--r--gpxe/src/net/iobpad.c2
-rw-r--r--gpxe/src/net/ipv4.c41
-rw-r--r--gpxe/src/net/mii.c147
-rw-r--r--gpxe/src/net/netdev_settings.c38
-rw-r--r--gpxe/src/net/netdevice.c66
-rw-r--r--gpxe/src/net/nullnet.c2
-rw-r--r--gpxe/src/net/rarp.c2
-rw-r--r--gpxe/src/net/retry.c3
-rw-r--r--gpxe/src/net/tcp.c141
-rw-r--r--gpxe/src/net/tcp/ftp.c30
-rw-r--r--gpxe/src/net/tcp/http.c64
-rw-r--r--gpxe/src/net/tcp/https.c2
-rw-r--r--gpxe/src/net/tcp/iscsi.c79
-rw-r--r--gpxe/src/net/tcpip.c17
-rw-r--r--gpxe/src/net/tls.c4
-rw-r--r--gpxe/src/net/udp.c4
-rw-r--r--gpxe/src/net/udp/dhcp.c419
-rw-r--r--gpxe/src/net/udp/dns.c4
-rw-r--r--gpxe/src/net/udp/slam.c6
-rw-r--r--gpxe/src/net/udp/tftp.c139
-rw-r--r--gpxe/src/proto/fsp.c243
-rw-r--r--gpxe/src/proto/igmp.c167
-rw-r--r--gpxe/src/proto/nfs.c616
-rw-r--r--gpxe/src/proto/nmb.c110
-rw-r--r--gpxe/src/tests/uri_test.c7
-rw-r--r--gpxe/src/usr/autoboot.c64
-rw-r--r--gpxe/src/usr/dhcpmgmt.c23
-rw-r--r--gpxe/src/usr/ifmgmt.c42
-rw-r--r--gpxe/src/usr/imgmgmt.c4
-rw-r--r--gpxe/src/usr/iwmgmt.c244
-rw-r--r--gpxe/src/usr/pxemenu.c4
-rw-r--r--gpxe/src/usr/route.c4
-rw-r--r--gpxe/src/util/.gitignore1
-rwxr-xr-xgpxe/src/util/diffsize.pl101
-rwxr-xr-xgpxe/src/util/dskpad.pl12
-rw-r--r--gpxe/src/util/elf2efi.c7
-rwxr-xr-xgpxe/src/util/geniso5
-rwxr-xr-xgpxe/src/util/genliso51
-rwxr-xr-xgpxe/src/util/gensdsk65
-rw-r--r--gpxe/src/util/iccfix.c156
-rwxr-xr-xgpxe/src/util/licence.pl149
-rwxr-xr-xgpxe/src/util/makerom.pl30
-rwxr-xr-xgpxe/src/util/modrom.pl4
-rwxr-xr-xgpxe/src/util/padimg.pl44
-rw-r--r--gpxe/src/util/parserom.pl3
-rw-r--r--gpxe/src/util/zbin.c144
-rw-r--r--linux/Makefile2
-rw-r--r--memdisk/Makefile2
-rw-r--r--memdisk/inflate.c2
-rw-r--r--memdisk/setup.c46
-rw-r--r--memdump/Makefile2
-rw-r--r--memdump/file.h25
-rw-r--r--memdump/main.c30
-rw-r--r--memdump/serial.c5
-rw-r--r--memdump/srecsend.c75
-rw-r--r--memdump/srecsend.h10
-rw-r--r--memdump/stdbool.h32
-rw-r--r--memdump/ymsend.h18
-rw-r--r--mtools/Makefile2
-rw-r--r--mtools/syslinux.c5
-rw-r--r--syslinux.spec.in7
-rw-r--r--utils/Makefile2
-rw-r--r--utils/mkdiskimage.in16
-rw-r--r--version2
-rw-r--r--win32/Makefile4
834 files changed, 70265 insertions, 10317 deletions
diff --git a/MCONFIG b/MCONFIG
index a716c6c5..e9c16d38 100644
--- a/MCONFIG
+++ b/MCONFIG
@@ -60,6 +60,11 @@ WGET = wget
com32 = $(topdir)/com32
+# Common warnings we want for all gcc-generated code
+GCCWARN := -W -Wall -Wstrict-prototypes
+# Extremely useful variant for debugging...
+#GCCWARN += -Wno-clobbered -Werror
+
# Common stanza to make gcc generate .*.d dependency files
MAKEDEPS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d
diff --git a/MCONFIG.embedded b/MCONFIG.embedded
index 586afc3e..4b42e0da 100644
--- a/MCONFIG.embedded
+++ b/MCONFIG.embedded
@@ -16,19 +16,21 @@
include $(topdir)/MCONFIG
-GCCOPT := $(call gcc_ok,-m32,) \
- $(call gcc_ok,-ffreestanding,) \
- $(call gcc_ok,-fno-stack-protector,) \
- $(call gcc_ok,-falign-functions=0,-malign-functions=0) \
- $(call gcc_ok,-falign-jumps=0,-malign-jumps=0) \
- $(call gcc_ok,-falign-loops=0,-malign-loops=0) \
+GCCOPT := $(call gcc_ok,-m32,) \
+ $(call gcc_ok,-ffreestanding,) \
+ $(call gcc_ok,-fno-stack-protector,) \
+ $(call gcc_ok,-falign-functions=0,-malign-functions=0) \
+ $(call gcc_ok,-falign-jumps=0,-malign-jumps=0) \
+ $(call gcc_ok,-falign-loops=0,-malign-loops=0) \
+ $(call gcc_ok,-mpreferred-stack-boundary=2,) \
+ $(call gcc_ok,-mincoming-stack-boundary=2,) \
-march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3 \
-msoft-float
LIBGCC := $(shell $(CC) $(GCCOPT) --print-libgcc)
LD += -m elf_i386
-CFLAGS = $(GCCOPT) -g -W -Wall -Wno-sign-compare $(OPTFLAGS) $(INCLUDES)
+CFLAGS = $(GCCOPT) -g $(GCCWARN) -Wno-sign-compare $(OPTFLAGS) $(INCLUDES)
SFLAGS = $(CFLAGS) -D__ASSEMBLY__
.SUFFIXES: .c .o .S .s .i .elf .com .bin .asm .lst .c32 .lss
diff --git a/Makefile b/Makefile
index d0f5e71d..2393faa6 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,8 @@ include $(topdir)/MCONFIG
# List of module objects that should be installed for all derivatives
MODULES = memdisk/memdisk memdump/memdump.com modules/*.com \
com32/menu/*.c32 com32/modules/*.c32 com32/mboot/*.c32 \
- com32/hdt/*.c32 com32/rosh/*.c32 com32/gfxboot/*.c32
+ com32/hdt/*.c32 com32/rosh/*.c32 com32/gfxboot/*.c32 \
+ com32/sysdump/*.c32
# syslinux.exe is BTARGET so as to not require everyone to have the
# mingw suite installed
@@ -55,7 +56,7 @@ BOBJECTS = $(BTARGET) \
BSUBDIRS = codepage core memdisk modules com32 mbr memdump gpxe sample \
libinstaller dos win32 dosutil
ITARGET =
-IOBJECTS = $(ITARGET) dos/copybs.com \
+IOBJECTS = $(ITARGET) \
utils/gethostip utils/isohybrid utils/mkdiskimage \
mtools/syslinux linux/syslinux extlinux/extlinux
ISUBDIRS = libinstaller mtools linux extlinux utils
@@ -67,7 +68,7 @@ INSTALL_SBIN = extlinux/extlinux
# Things to install in /usr/lib/syslinux
INSTALL_AUX = core/pxelinux.0 gpxe/gpxelinux.0 core/isolinux.bin \
core/isolinux-debug.bin \
- dos/syslinux.com dos/copybs.com win32/syslinux.exe \
+ dos/syslinux.com win32/syslinux.exe \
mbr/*.bin $(MODULES)
INSTALL_AUX_OPT = win32/syslinux.exe
diff --git a/NEWS b/NEWS
index 3f028ad7..83761e22 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,50 @@ Starting with 1.47, changes marked with SYSLINUX, PXELINUX, ISOLINUX
or EXTLINUX apply to that specific program only; other changes apply
to all derivatives.
+Changes in 3.86:
+ * chain.c32: fix chainloading the MBR of a hard disk (broken
+ in 3.85).
+ * mboot.c32: report the boot loader name in the information
+ structure.
+ * com32: set argv[0] in a com32 module.
+ * core: add a workaround for a bug in Xen HVM older than
+ version 3.3: disable halt on those platforms.
+ * Fix problems where certain operations in com32 modules would
+ cause the core to believe the system was idle.
+ * MEMDISK: fix MBR detection when used with a DOSEMU header or
+ an offset.
+ * MEMDISK: generate the mBFT checksum correctly.
+
+Changes in 3.85:
+ * gPXELINUX: updated to gPXE 1.0.0. gPXELINUX can now do NBP
+ chainloading, and does not require a second DHCP.
+ * vesamenu.c32: unbreak the default "grey hole" background.
+ * We no longer have a built-in default of "linux auto".
+ Instead, if no DEFAULT or UI statement is found, or the
+ configuration file is missing entirely, we drop to the boot:
+ prompt with an error message (if NOESCAPE is set, we stop
+ with a "boot failed" message; this is also the case for
+ PXELINUX if the configuration file is not found.)
+ * chain.c32: support chainloading Grub4DOS; patch by Gert
+ Hulselmans.
+ * New tool: sysdump.c32, can be used to produce system
+ information for debugging via tftp or ymodem (serial port).
+ * "vga=current" on the Linux command line is now supported.
+ * chain.c32: support for Windows Recovery Console, via the
+ "cmldr=" option.
+ * chain.c32: should now support loading NTLDR from different
+ type media than loaded from.
+ * chain.c32: support chainloading to a FAT/NTFS partition with
+ invalid "hidden sectors" via the "sethidden" option.
+ * memdisk: fix the mBFT ACPI table.
+ * vesamenu.c32: if the image is smaller than the screen, tile
+ it across the whole screen.
+ * mkdiskimage: -s option for producing a sparse image.
+ * vesamenu.c32: support arbitrary resolution setting (beyond
+ BIOS support) on some Intel-based video chipsets. This code
+ is a modified version of the "915resolution" tool by
+ Steve Tomljenovic; your mileage might vary.
+
Changes in 3.84:
* SYSLINUX: make the DOS installer work for MS-DOS 7.x/8.x
(Win9x/ME) again.
@@ -20,6 +64,10 @@ Changes in 3.84:
experimental. This will replace gfxboot.com in the future.
* vesamenu.c32: new MENU RESOLUTION directive to set a screen
resolution other than 640x480.
+ * chain.c32: add support for loading isolinux.bin.
+ * chain.c32: make sure to always return to text mode.
+ * eltorito.sys: DOS driver for generic CD-ROMs; by Gary Tong
+ and Bart Lagerweij.
Changes in 3.83:
* PXELINUX: clear memory before handing over to a chainloaded
diff --git a/README b/README
index 0e92ea2e..aebc421c 100644
--- a/README
+++ b/README
@@ -25,7 +25,7 @@ for details.
SYSLINUX is:
- Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+ Copyright 1994-2010 H. Peter Anvin et al - 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
diff --git a/com32/MCONFIG b/com32/MCONFIG
index f8d9d978..0e152de3 100644
--- a/com32/MCONFIG
+++ b/com32/MCONFIG
@@ -17,10 +17,15 @@
include $(topdir)/MCONFIG
-GCCOPT := $(call gcc_ok,-std=gnu99,) \
- $(call gcc_ok,-m32,) \
- $(call gcc_ok,-fno-stack-protector,) \
- -mregparm=3 -DREGPARM=3 -march=i386 -Os
+GCCOPT := $(call gcc_ok,-std=gnu99,) \
+ $(call gcc_ok,-m32,) \
+ $(call gcc_ok,-fno-stack-protector,) \
+ $(call gcc_ok,-falign-functions=0,-malign-functions=0) \
+ $(call gcc_ok,-falign-jumps=0,-malign-jumps=0) \
+ $(call gcc_ok,-falign-loops=0,-malign-loops=0) \
+ $(call gcc_ok,-mpreferred-stack-boundary=2,) \
+ $(call gcc_ok,-mincoming-stack-boundary=2,) \
+ -march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3
com32 = $(topdir)/com32
@@ -32,11 +37,11 @@ GPLLIB =
GPLINCLUDE =
endif
-CFLAGS = $(GCCOPT) -W -Wall -march=i386 \
+CFLAGS = $(GCCOPT) $(GCCWARN) -march=i386 \
-fomit-frame-pointer -D__COM32__ \
-nostdinc -iwithprefix include \
-I$(com32)/libutil/include -I$(com32)/include $(GPLINCLUDE)
-SFLAGS = $(GCCOPT) -W -Wall -march=i386 \
+SFLAGS = $(GCCOPT) $(GCCWARN) -march=i386 \
-fomit-frame-pointer -D__COM32__ \
-nostdinc -iwithprefix include \
-I$(com32)/libutil/include -I$(com32)/include $(GPLINCLUDE)
@@ -45,7 +50,7 @@ COM32LD = $(com32)/lib/com32.ld
LDFLAGS = -m elf_i386 -T $(COM32LD)
LIBGCC := $(shell $(CC) $(GCCOPT) --print-libgcc)
-LNXCFLAGS = -I$(com32)/libutil/include -W -Wall -O -g -D_GNU_SOURCE
+LNXCFLAGS = -I$(com32)/libutil/include $(GCCWARN) -O -g -D_GNU_SOURCE
LNXSFLAGS = -g
LNXLDFLAGS = -g
diff --git a/com32/Makefile b/com32/Makefile
index 69a125e6..3821e581 100644
--- a/com32/Makefile
+++ b/com32/Makefile
@@ -1,3 +1,4 @@
-SUBDIRS = lib gpllib libutil modules mboot menu samples rosh cmenu hdt gfxboot
+SUBDIRS = lib gpllib libutil modules mboot menu samples rosh cmenu \
+ hdt gfxboot sysdump
all tidy dist clean spotless install:
set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
diff --git a/com32/cmenu/adv_menu.tpl b/com32/cmenu/adv_menu.tpl
index be3c558e..a1a5d96a 100644
--- a/com32/cmenu/adv_menu.tpl
+++ b/com32/cmenu/adv_menu.tpl
@@ -183,12 +183,12 @@ TIMEOUTCODE timeout(const char *cmd)
}
}
-TIMEOUTCODE ontimeout()
+TIMEOUTCODE ontimeout(void)
{
return timeout(timeoutcmd);
}
-TIMEOUTCODE ontotaltimeout()
+TIMEOUTCODE ontotaltimeout(void)
{
return timeout(totaltimeoutcmd);
}
diff --git a/com32/cmenu/complex.c b/com32/cmenu/complex.c
index 1ac51997..f5175fa9 100644
--- a/com32/cmenu/complex.c
+++ b/com32/cmenu/complex.c
@@ -54,7 +54,7 @@ char username[12]; // Name of user currently using the system
/* End globals */
-TIMEOUTCODE ontimeout()
+TIMEOUTCODE ontimeout(void)
{
beep();
return CODE_WAIT;
@@ -244,7 +244,7 @@ t_handler_return checkbox_handler(t_menusystem * ms, t_menuitem * mi)
return rv;
}
-int main()
+int main(void)
{
t_menuitem *curr;
char cmd[160];
diff --git a/com32/cmenu/libmenu/menu.c b/com32/cmenu/libmenu/menu.c
index de4a1ee2..13754768 100644
--- a/com32/cmenu/libmenu/menu.c
+++ b/com32/cmenu/libmenu/menu.c
@@ -40,7 +40,7 @@ int isvisible(pt_menu menu, int first, int curr);
// This is same as inputc except it honors the ontimeout handler
// and calls it when needed. For the callee, there is no difference
// as this will not return unless a key has been pressed.
-static int getch()
+static int getch(void)
{
t_timeout_handler th;
int key;
@@ -615,7 +615,7 @@ uchar find_menu_num(const char *name)
// Run through all items and if they are submenus
// with a non-trivial "action" and trivial submenunum
// replace submenunum with the menu with name "action"
-void fix_submenus()
+void fix_submenus(void)
{
int i, j;
pt_menu m;
@@ -874,7 +874,7 @@ void reg_ontimeout(t_timeout_handler handler, unsigned int numsteps,
ms->tm_stepsize = stepsize;
}
-void unreg_ontimeout()
+void unreg_ontimeout(void)
{
ms->ontimeout = NULL;
}
@@ -889,7 +889,7 @@ void reg_ontotaltimeout(t_timeout_handler handler,
}
}
-void unreg_ontotaltimeout()
+void unreg_ontotaltimeout(void)
{
ms->ontotaltimeout = NULL;
}
@@ -1084,7 +1084,7 @@ void set_menu_pos(uchar row, uchar col) // Set the position of this menu.
m->col = col;
}
-pt_menuitem add_sep() // Add a separator to current menu
+pt_menuitem add_sep(void) // Add a separator to current menu
{
pt_menuitem mi;
pt_menu m;
diff --git a/com32/cmenu/libmenu/menu.h b/com32/cmenu/libmenu/menu.h
index a1356020..141d2ef0 100644
--- a/com32/cmenu/libmenu/menu.h
+++ b/com32/cmenu/libmenu/menu.h
@@ -225,7 +225,7 @@ pt_menuitem showmenus(uchar startmenu);
pt_menusystem init_menusystem(const char *title);
-void close_menusystem(); // Deallocate memory used
+void close_menusystem(void); // Deallocate memory used
void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal,
uchar inactiveselected);
@@ -253,10 +253,10 @@ void reg_ontimeout(t_timeout_handler, unsigned int numsteps,
unsigned int stepsize);
// Set timeout handler, set 0 for default values.
// So stepsize=0 means numsteps is measured in centiseconds.
-void unreg_ontimeout();
+void unreg_ontimeout(void);
void reg_ontotaltimeout(t_timeout_handler, unsigned long numcentiseconds);
-void unreg_ontotaltimeout();
+void unreg_ontotaltimeout(void);
// Find the number of the menu given the name
// Returns -1 if not found
@@ -284,7 +284,7 @@ static inline void set_shortcut(uchar shortcut)
}
// Add a separator to the "current" menu
-pt_menuitem add_sep();
+pt_menuitem add_sep(void);
// Generate string based on state of checkboxes and radioitem in given menu
// and append string to existing contents of "line"
diff --git a/com32/cmenu/libmenu/passwords.c b/com32/cmenu/libmenu/passwords.c
index 06f4cfb3..44ce461f 100644
--- a/com32/cmenu/libmenu/passwords.c
+++ b/com32/cmenu/libmenu/passwords.c
@@ -148,7 +148,7 @@ void init_passwords(const char *filename)
fclose(f);
}
-void close_passwords()
+void close_passwords(void)
{
int i;
diff --git a/com32/gfxboot/.gitignore b/com32/gfxboot/.gitignore
new file mode 100644
index 00000000..1944fd61
--- /dev/null
+++ b/com32/gfxboot/.gitignore
@@ -0,0 +1 @@
+*.tmp
diff --git a/com32/gfxboot/Makefile b/com32/gfxboot/Makefile
index 2affcdea..73133e1b 100644
--- a/com32/gfxboot/Makefile
+++ b/com32/gfxboot/Makefile
@@ -22,8 +22,8 @@ gfxboot.elf : gfxboot.o realmode_callback.o $(LIBS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
realmode_callback.o: realmode_callback.asm
- nasm -f bin -O99 -o $*.tmp -l $*.lst $<
- objcopy -B i386 -I binary -O elf32-i386 \
+ $(NASM) -f bin -O99 -o $*.tmp -l $*.lst $<
+ $(OBJCOPY) -B i386 -I binary -O elf32-i386 \
--redefine-sym _binary_$*_tmp_start=$*_start \
--redefine-sym _binary_$*_tmp_end=$*_end \
--strip-symbol _binary_$*_tmp_size \
diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c
index e1b865a1..a6c95fe1 100644
--- a/com32/gfxboot/gfxboot.c
+++ b/com32/gfxboot/gfxboot.c
@@ -116,13 +116,15 @@ typedef struct __attribute__ ((packed)) {
// menu description
typedef struct menu_s {
struct menu_s *next;
- char *label;
- char *kernel;
- char *linux;
- char *localboot;
- char *initrd;
- char *append;
- char *ipappend;
+ char *label; // config entry name
+ char *menu_label; // text to show in boot menu
+ char *kernel; // name of program to load
+ char *alt_kernel; // alternative name in case user has replaced it
+ char *linux; // de facto an alias for 'kernel'
+ char *localboot; // boot from local disk
+ char *initrd; // initrd as separate line (instead of as part of 'append')
+ char *append; // kernel args
+ char *ipappend; // append special pxelinux args (see doc)
} menu_t;
@@ -149,6 +151,9 @@ char cmdline[MAX_CMDLINE_LEN];
void *save_buf;
unsigned save_buf_size;
+// progress bar is visible
+unsigned progress_active;
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void show_message(char *file);
@@ -163,9 +168,13 @@ int gfx_init(char *file);
int gfx_menu_init(void);
void gfx_done(void);
int gfx_input(void);
+void gfx_infobox(int type, char *str1, char *str2);
+void gfx_progress_init(ssize_t kernel_size, char *label);
+void gfx_progress_update(ssize_t size);
+void gfx_progress_done(void);
ssize_t save_read(int fd, void *buf, size_t size);
void *load_one(char *file, ssize_t *file_size);
-void boot(void);
+void boot(int index);
void boot_entry(menu_t *menu_ptr, char *arg);
@@ -234,7 +243,7 @@ int main(int argc, char **argv)
}
// does not return if it succeeds
- boot();
+ boot(menu_index);
}
if(argc > 2) show_message(argv[2]);
@@ -321,59 +330,73 @@ int read_config_file(void)
if(*t) *t++ = 0;
t = skip_spaces(t);
- if(!strcmp(s, "timeout")) {
+ if(!strcasecmp(s, "timeout")) {
timeout = atoi(t);
continue;
}
- if(!strcmp(s, "default")) {
+ if(!strcasecmp(s, "default")) {
menu_default->label = strdup(t);
u = strlen(t);
if(u > label_size) label_size = u;
continue;
}
- if(!strcmp(s, "label")) {
+ if(!strcasecmp(s, "label")) {
menu_ptr = *menu_next = calloc(1, sizeof **menu_next);
menu_next = &menu_ptr->next;
menu_idx++;
- menu_ptr->label = strdup(t);
+ menu_ptr->label = menu_ptr->menu_label = strdup(t);
u = strlen(t);
if(u > label_size) label_size = u;
continue;
}
- if(!strcmp(s, "kernel") && menu_ptr) {
+ if(!strcasecmp(s, "kernel") && menu_ptr) {
menu_ptr->kernel = strdup(t);
continue;
}
- if(!strcmp(s, "linux") && menu_ptr) {
+ if(!strcasecmp(s, "linux") && menu_ptr) {
menu_ptr->linux = strdup(t);
continue;
}
- if(!strcmp(s, "localboot") && menu_ptr) {
+ if(!strcasecmp(s, "localboot") && menu_ptr) {
menu_ptr->localboot = strdup(t);
continue;
}
- if(!strcmp(s, "initrd") && menu_ptr) {
+ if(!strcasecmp(s, "initrd") && menu_ptr) {
menu_ptr->initrd = strdup(t);
continue;
}
- if(!strcmp(s, "append")) {
+ if(!strcasecmp(s, "append")) {
(menu_ptr ?: menu_default)->append = strdup(t);
u = strlen(t);
if(u > append_size) append_size = u;
continue;
}
- if(!strcmp(s, "ipappend")) {
+ if(!strcasecmp(s, "ipappend")) {
(menu_ptr ?: menu_default)->ipappend = strdup(t);
continue;
}
+
+ if(!strcasecmp(s, "menu") && menu_ptr) {
+ s = skip_spaces(t);
+ t = skip_nonspaces(s);
+ if(*t) *t++ = 0;
+ t = skip_spaces(t);
+
+ if(!strcasecmp(s, "label")) {
+ menu_ptr->menu_label = strdup(t);
+ u = strlen(t);
+ if(u > label_size) label_size = u;
+ continue;
+ }
+ }
}
fclose(f);
@@ -382,15 +405,22 @@ int read_config_file(void)
label_size++;
append_size++;
- gfx_menu.entries = menu_idx;
- gfx_menu.label_size = label_size;
- gfx_menu.arg_size = append_size;
+ // ensure we have a default entry
+ if(!menu_default->label) menu_default->label = menu->label;
- gfx_menu.default_entry = menu_default->label;
- if(!gfx_menu.default_entry && menu) {
- gfx_menu.default_entry = menu->label;
+ if(menu_default->label) {
+ for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next) {
+ if(!strcmp(menu_default->label, menu_ptr->label)) {
+ menu_default->menu_label = menu_ptr->menu_label;
+ break;
+ }
+ }
}
+ gfx_menu.entries = menu_idx;
+ gfx_menu.label_size = label_size;
+ gfx_menu.arg_size = append_size;
+ gfx_menu.default_entry = menu_default->menu_label;
gfx_menu.label_list = calloc(menu_idx, label_size);
gfx_menu.arg_list = calloc(menu_idx, append_size);
@@ -398,7 +428,7 @@ int read_config_file(void)
if(!menu_ptr->append) menu_ptr->append = menu_default->append;
if(!menu_ptr->ipappend) menu_ptr->ipappend = menu_default->ipappend;
- if(menu_ptr->label) strcpy(gfx_menu.label_list + u * label_size, menu_ptr->label);
+ if(menu_ptr->menu_label) strcpy(gfx_menu.label_list + u * label_size, menu_ptr->menu_label);
if(menu_ptr->append) strcpy(gfx_menu.arg_list + u * append_size, menu_ptr->append);
}
@@ -424,7 +454,7 @@ unsigned magic_ok(unsigned char *buf, unsigned *code_size)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// Search cpio archive for gfx file.
+// Search (cpio archive) for gfx file.
//
unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len, unsigned *code_size)
{
@@ -433,6 +463,8 @@ unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, u
*gfx_file_start = 0;
*code_size = 0;
+ if((code_start = magic_ok(buf, code_size))) return code_start;
+
for(i = 0; i < len;) {
if((len - i) >= 0x1a && (buf[i] + (buf[i + 1] << 8)) == 0x71c7) {
fname_len = *(unsigned short *) (buf + i + 20);
@@ -470,6 +502,8 @@ int gfx_init(char *file)
void *lowmem = lowmem_buf;
unsigned lowmem_size = lowmem_buf_size;
+ progress_active = 0;
+
printf("Loading %s...\n", file);
if(loadfile(file, &archive, &archive_size)) return 1;
@@ -571,7 +605,7 @@ int gfx_init(char *file)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int gfx_menu_init()
+int gfx_menu_init(void)
{
com32sys_t r;
@@ -583,10 +617,12 @@ int gfx_menu_init()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void gfx_done()
+void gfx_done(void)
{
com32sys_t r;
+ gfx_progress_done();
+
__farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_DONE], &r, &r);
}
@@ -597,7 +633,7 @@ void gfx_done()
// return:
// boot menu index (-1: go to text mode prompt)
//
-int gfx_input()
+int gfx_input(void)
{
com32sys_t r;
@@ -615,6 +651,61 @@ int gfx_input()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_infobox(int type, char *str1, char *str2)
+{
+ com32sys_t r;
+
+ r.eax.l = type;
+ r.esi.l = (uint32_t) str1;
+ r.edi.l = (uint32_t) str2;
+ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INFOBOX_INIT], &r, &r);
+ r.edi.l = r.eax.l = 0;
+ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INPUT], &r, &r);
+ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INFOBOX_DONE], &r, &r);
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_progress_init(ssize_t kernel_size, char *label)
+{
+ com32sys_t r;
+
+ if(!progress_active) {
+ r.eax.l = kernel_size >> gfx_config.sector_shift; // in sectors
+ r.esi.l = (uint32_t) label;
+ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_INIT], &r, &r);
+ }
+
+ progress_active = 1;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_progress_update(ssize_t advance)
+{
+ com32sys_t r;
+
+ if(progress_active) {
+ r.eax.l = advance >> gfx_config.sector_shift; // in sectors
+ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_UPDATE], &r, &r);
+ }
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_progress_done(void)
+{
+ com32sys_t r;
+
+ if(progress_active) {
+ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_DONE], &r, &r);
+ }
+
+ progress_active = 0;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Like read(2) but preserve bounce buffer.
//
ssize_t save_read(int fd, void *buf, size_t size)
@@ -636,14 +727,16 @@ void *load_one(char *file, ssize_t *file_size)
{
int fd;
void *buf = NULL;
+ char *str;
struct stat sbuf;
ssize_t size = 0, cur, i;
- com32sys_t r;
*file_size = 0;
if((fd = open(file, O_RDONLY)) == -1) {
- printf("%s: file not found\n", file);
+ asprintf(&str, "%s: file not found", file);
+ gfx_infobox(0, str, NULL);
+ free(str);
return buf;
}
@@ -655,23 +748,26 @@ void *load_one(char *file, ssize_t *file_size)
buf = malloc(size);
for(i = 1, cur = 0 ; cur < size && i > 0; cur += i) {
i = save_read(fd, buf + cur, CHUNK_SIZE);
- r.eax.l = i >> gfx_config.sector_shift;
- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_UPDATE], &r, &r);
+ if(i == -1) break;
+ gfx_progress_update(i);
}
}
else {
do {
buf = realloc(buf, size + CHUNK_SIZE);
i = save_read(fd, buf + size, CHUNK_SIZE);
+ if(i == -1) break;
size += i;
- r.eax.l = i >> gfx_config.sector_shift;
- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_UPDATE], &r, &r);
+ gfx_progress_update(i);
} while(i > 0);
}
close(fd);
if(i == -1) {
+ asprintf(&str, "%s: read error @ %d", file, size);
+ gfx_infobox(0, str, NULL);
+ free(str);
free(buf);
buf = NULL;
size = 0;
@@ -684,22 +780,54 @@ void *load_one(char *file, ssize_t *file_size)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// Locate menu entry and boot.
+// Boot menu entry.
//
-void boot()
+// cmdline can optionally start with label string.
+//
+void boot(int index)
{
- char *label, *arg, *s;
+ char *arg, *alt_kernel;
menu_t *menu_ptr;
+ int i, label_len;
+ unsigned ipapp;
+ const struct syslinux_ipappend_strings *ipappend;
+
+ for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, index--) {
+ if(!index) break;
+ }
+
+ // invalid index or menu entry
+ if(!menu_ptr || !menu_ptr->menu_label) return;
- label = skip_spaces(cmdline);
- arg = skip_spaces(s = skip_nonspaces(label));
- *s = 0;
+ arg = skip_spaces(cmdline);
+ label_len = strlen(menu_ptr->menu_label);
- for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next) {
- if(menu_ptr->label && !strcmp(menu_ptr->label, label)) break;
+ // if it does not start with label string, assume first word is kernel name
+ if(strncmp(arg, menu_ptr->menu_label, label_len)) {
+ alt_kernel = arg;
+ arg = skip_nonspaces(arg);
+ if(*arg) *arg++ = 0;
+ if(*alt_kernel) menu_ptr->alt_kernel = alt_kernel;
+ }
+ else {
+ arg += label_len;
+ }
+
+ arg = skip_spaces(arg);
+
+ // handle IPAPPEND
+ if(menu_ptr->ipappend && (ipapp = atoi(menu_ptr->ipappend))) {
+ ipappend = syslinux_ipappend_strings();
+ for(i = 0; i < ipappend->count; i++) {
+ if((ipapp & (1 << i)) && ipappend->ptr[i]) {
+ sprintf(arg + strlen(arg), " %s", ipappend->ptr[i]);
+ }
+ }
}
boot_entry(menu_ptr, arg);
+
+ gfx_progress_done();
}
@@ -716,39 +844,41 @@ void boot_entry(menu_t *menu_ptr, char *arg)
char *file, *cmd_buf;
int fd;
struct stat sbuf;
- com32sys_t r;
char *s, *s0, *t, *initrd_arg;
if(!menu_ptr) return;
if(menu_ptr->localboot) {
gfx_done();
- syslinux_local_boot(atoi(arg));
+ syslinux_local_boot(strtol(menu_ptr->localboot, NULL, 0));
return;
}
- file = menu_ptr->kernel;
+ file = menu_ptr->alt_kernel;
+ if(!file) file = menu_ptr->kernel;
if(!file) file = menu_ptr->linux;
- if(!file) return;
+ if(!file) {
+ gfx_done();
+ asprintf(&cmd_buf, "%s %s", menu_ptr->label, arg);
+ syslinux_run_command(cmd_buf);
+ return;
+ }
// first, load kernel
- r.eax.l = 0; // kernel size in sectors
+ kernel_size = 0;
if((fd = open(file, O_RDONLY)) >= 0) {
- if(!fstat(fd, &sbuf) && S_ISREG(sbuf.st_mode)) r.eax.l = sbuf.st_size >> gfx_config.sector_shift;
+ if(!fstat(fd, &sbuf) && S_ISREG(sbuf.st_mode)) kernel_size = sbuf.st_size;
close(fd);
}
- r.esi.l = (uint32_t) file;
- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_INIT], &r, &r);
+ gfx_progress_init(kernel_size, file);
kernel = load_one(file, &kernel_size);
if(!kernel) {
- gfx_done();
- printf("%s: read error\n", file);
return;
}
@@ -798,7 +928,7 @@ void boot_entry(menu_t *menu_ptr, char *arg)
free(s0);
- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_DONE], &r, &r);
+ gfx_done();
syslinux_boot_linux(kernel, kernel_size, initrd, arg);
}
diff --git a/com32/gfxboot/realmode_callback.asm b/com32/gfxboot/realmode_callback.asm
index fb5461d9..2ff30f26 100644
--- a/com32/gfxboot/realmode_callback.asm
+++ b/com32/gfxboot/realmode_callback.asm
@@ -111,7 +111,7 @@ cb_fread_90:
; edx filename
;
cb_getcwd:
- mov ax,15h
+ mov ax,1fh
int 22h
mov edx,es
shl edx,4
diff --git a/com32/gplinclude/disk/bootloaders.h b/com32/gplinclude/disk/bootloaders.h
index 5a6ff9d9..56a0f4e3 100644
--- a/com32/gplinclude/disk/bootloaders.h
+++ b/com32/gplinclude/disk/bootloaders.h
@@ -14,6 +14,6 @@
#include <disk/geom.h>
#include <disk/partition.h>
-int get_bootloader_string(const struct driveinfo *, const struct part_entry *,
+int get_bootloader_string(struct driveinfo *, const struct part_entry *,
char *, const int);
#endif /* __BOOTLOADERS_H_ */
diff --git a/com32/gpllib/cpuid.c b/com32/gpllib/cpuid.c
index fa212045..f33e8958 100644
--- a/com32/gpllib/cpuid.c
+++ b/com32/gpllib/cpuid.c
@@ -232,8 +232,10 @@ void generic_identify(struct cpuinfo_x86 *c)
}
break;
case X86_VENDOR_INTEL:
- cpuid(0x4, &eax, &ebx, &ecx, &edx);
- c->x86_num_cores = ((eax & 0xfc000000) >> 26) + 1;
+ if (c->cpuid_level >= 0x00000004) {
+ cpuid(0x4, &eax, &ebx, &ecx, &edx);
+ c->x86_num_cores = ((eax & 0xfc000000) >> 26) + 1;
+ }
break;
default:
c->x86_num_cores = 1;
diff --git a/com32/gpllib/disk/ata.c b/com32/gpllib/disk/ata.c
index b0c2b63c..78f669ec 100644
--- a/com32/gpllib/disk/ata.c
+++ b/com32/gpllib/disk/ata.c
@@ -55,7 +55,7 @@ void ata_id_c_string(const uint16_t * id, unsigned char *s,
ata_id_string(id, s, ofs, len - 1);
- p = s + strnlen(s, len - 1);
+ p = s + strnlen((const char *)s, len - 1);
while (p > s && p[-1] == ' ')
p--;
*p = '\0';
diff --git a/com32/gpllib/disk/bootloaders.c b/com32/gpllib/disk/bootloaders.c
index 29aecbd4..188dd64b 100644
--- a/com32/gpllib/disk/bootloaders.c
+++ b/com32/gpllib/disk/bootloaders.c
@@ -22,7 +22,7 @@
* @buffer: pre-allocated buffer
* @buffer_size: @buffer size
**/
-int get_bootloader_string(const struct driveinfo *d, const struct part_entry *p,
+int get_bootloader_string(struct driveinfo *d, const struct part_entry *p,
char *buffer, const int buffer_size)
{
char boot_sector[SECTOR * sizeof(char)];
diff --git a/com32/gpllib/dmi/dmi_processor.c b/com32/gpllib/dmi/dmi_processor.c
index fd007da3..1cd9d1ba 100644
--- a/com32/gpllib/dmi/dmi_processor.c
+++ b/com32/gpllib/dmi/dmi_processor.c
@@ -49,7 +49,7 @@ const char *dmi_processor_type(uint8_t code)
const char *dmi_processor_family(uint8_t code, char *manufacturer)
{
/* 3.3.5.2 */
- static const char *family[] = {
+ static const char *family[256] = {
NULL, /* 0x00 */
"Other",
"Unknown",
@@ -306,54 +306,6 @@ const char *dmi_processor_family(uint8_t code, char *manufacturer)
NULL,
NULL,
NULL, /* 0xFF */
- NULL,
- NULL,
- NULL,
- NULL,
- "SH-3",
- "SH-4",
- NULL, /*0x106*/
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /*0x110*/
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "ARM",
- "StrongARM",
- NULL, /*0x19A*/
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /*0x120*/
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /*0x12A*/
- NULL,
- "6x86",
- "MediaGX",
- "MII" /*0x12E*/
- /* master.mif has values beyond that, but they can't be used for DMI */
};
/* Special case for ambiguous value 0xBE */
if (code == 0xBE) {
@@ -367,7 +319,7 @@ const char *dmi_processor_family(uint8_t code, char *manufacturer)
return "Core 2 or K7";
}
- if ((code<=0x12E) && (family[code] != NULL)) {
+ if (family[code] != NULL) {
return family[code];
}
return out_of_spec;
diff --git a/com32/hdt/hdt-cli-syslinux.c b/com32/hdt/hdt-cli-syslinux.c
index 6c231ed5..302ca24a 100644
--- a/com32/hdt/hdt-cli-syslinux.c
+++ b/com32/hdt/hdt-cli-syslinux.c
@@ -42,10 +42,10 @@ void main_show_syslinux(int argc __unused, char **argv __unused,
reset_more_printf();
more_printf("SYSLINUX\n");
more_printf(" Bootloader : %s\n", hardware->syslinux_fs);
- more_printf(" Version : %s\n", hardware->sv->version_string + 2);
+ more_printf(" Version : %s\n", hardware->sv->version_string);
more_printf(" Version : %u\n", hardware->sv->version);
more_printf(" Max API : %u\n", hardware->sv->max_api);
- more_printf(" Copyright : %s\n", hardware->sv->copyright_string + 1);
+ more_printf(" Copyright : %s\n", hardware->sv->copyright_string);
}
struct cli_module_descr syslinux_show_modules = {
diff --git a/com32/hdt/hdt-cli.c b/com32/hdt/hdt-cli.c
index 69a2b61f..76aed784 100644
--- a/com32/hdt/hdt-cli.c
+++ b/com32/hdt/hdt-cli.c
@@ -96,7 +96,7 @@ static void autocomplete_add_token_to_list(const char *token)
autocomplete_tail = new;
}
-static void autocomplete_destroy_list()
+static void autocomplete_destroy_list(void)
{
struct autocomplete_list *tmp = NULL;
@@ -727,7 +727,7 @@ out:
free(argv);
}
-static void reset_prompt()
+static void reset_prompt(void)
{
/* No need to display the prompt if we exit */
if (hdt_cli.mode != EXIT_MODE) {
@@ -779,7 +779,7 @@ void start_auto_mode(struct s_hardware *hardware)
more_printf("\n");
}
-void print_history()
+void print_history(void)
{
reset_more_printf();
for (int i = 1; i <= MAX_HISTORY_SIZE; i++) {
diff --git a/com32/hdt/hdt-cli.h b/com32/hdt/hdt-cli.h
index 898b53f8..b55d108a 100644
--- a/com32/hdt/hdt-cli.h
+++ b/com32/hdt/hdt-cli.h
@@ -160,7 +160,7 @@ void start_auto_mode(struct s_hardware *hardware);
void main_show(char *item, struct s_hardware *hardware);
#define CLI_HISTORY "history"
-void print_history();
+void print_history(void);
// DMI STUFF
#define CLI_DMI_BASE_BOARD "base_board"
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index 59175cec..736d9b6e 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -649,7 +649,7 @@ char *del_multi_spaces(char *p)
}
/* Reset the more_printf counter */
-void reset_more_printf()
+void reset_more_printf(void)
{
display_line_nb = 0;
}
diff --git a/com32/hdt/hdt-common.h b/com32/hdt/hdt-common.h
index d7a58e2f..0a0c8c4e 100644
--- a/com32/hdt/hdt-common.h
+++ b/com32/hdt/hdt-common.h
@@ -201,7 +201,7 @@ struct s_hardware {
char vesa_background[255];
};
-void reset_more_printf();
+void reset_more_printf(void);
const char *find_argument(const char **argv, const char *argument);
char *remove_spaces(char *p);
char *remove_trailing_lf(char *p);
diff --git a/com32/hdt/hdt-menu-syslinux.c b/com32/hdt/hdt-menu-syslinux.c
index c85bfbf4..02de5b31 100644
--- a/com32/hdt/hdt-menu-syslinux.c
+++ b/com32/hdt/hdt-menu-syslinux.c
@@ -51,9 +51,9 @@ void compute_syslinuxmenu(struct s_my_menu *menu, struct s_hardware *hardware)
menu->items_count++;
snprintf(buffer, sizeof buffer, "Version : %s",
- hardware->sv->version_string + 2);
+ hardware->sv->version_string);
snprintf(statbuffer, sizeof statbuffer, "Version: %s",
- hardware->sv->version_string + 2);
+ hardware->sv->version_string);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
@@ -71,10 +71,10 @@ void compute_syslinuxmenu(struct s_my_menu *menu, struct s_hardware *hardware)
add_item("", "", OPT_SEP, "", 0);
- snprintf(buffer, sizeof buffer, "%s", hardware->sv->copyright_string + 1);
+ snprintf(buffer, sizeof buffer, "%s", hardware->sv->copyright_string);
/* Remove the trailing LF in the copyright string to avoid scrolling */
snprintf(statbuffer, sizeof statbuffer, "%s",
- remove_trailing_lf(hardware->sv->copyright_string + 1));
+ remove_trailing_lf(hardware->sv->copyright_string));
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
diff --git a/com32/hdt/hdt-menu.c b/com32/hdt/hdt-menu.c
index 1aa0906f..4629ee58 100644
--- a/com32/hdt/hdt-menu.c
+++ b/com32/hdt/hdt-menu.c
@@ -79,7 +79,7 @@ int start_menu_mode(struct s_hardware *hardware, char *version_string)
}
/* In the menu system, what to do on keyboard timeout */
-TIMEOUTCODE ontimeout()
+TIMEOUTCODE ontimeout(void)
{
// beep();
return CODE_WAIT;
diff --git a/com32/hdt/hdt-menu.h b/com32/hdt/hdt-menu.h
index f10e5290..c8c91243 100644
--- a/com32/hdt/hdt-menu.h
+++ b/com32/hdt/hdt-menu.h
@@ -82,7 +82,7 @@ struct s_hdt_menu {
int total_menu_count; // Sum of all menus we have
};
-TIMEOUTCODE ontimeout();
+TIMEOUTCODE ontimeout(void);
void keys_handler(t_menusystem * ms
__attribute__ ((unused)), t_menuitem * mi, int scancode);
diff --git a/com32/include/com32.h b/com32/include/com32.h
index aa7fb4b6..665fa0bf 100644
--- a/com32/include/com32.h
+++ b/com32/include/com32.h
@@ -95,12 +95,13 @@ typedef struct {
extern struct com32_sys_args {
uint32_t cs_sysargs;
char *cs_cmdline;
- void __cdecl(*cs_intcall) (uint8_t, const com32sys_t *, com32sys_t *);
+ void __cdecl (*cs_intcall)(uint8_t, const com32sys_t *, com32sys_t *);
void *cs_bounce;
uint32_t cs_bounce_size;
- void __cdecl(*cs_farcall) (uint32_t, const com32sys_t *, com32sys_t *);
- int __cdecl(*cs_cfarcall) (uint32_t, const void *, uint32_t);
+ void __cdecl (*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *);
+ int __cdecl (*cs_cfarcall)(uint32_t, const void *, uint32_t);
uint32_t cs_memsize;
+ const char *cs_name;
} __com32;
/*
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index 168a5160..868b0f10 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -110,7 +110,7 @@ union syslinux_derivative_info {
uint32_t _edi, _esi, _ebp, _esp, _ebx;
uint16_t apiver;
uint16_t _dxh;
- uint32_t _ecx;
+ uint32_t myip;
uint8_t filesystem, ah;
uint16_t _axh;
uint32_t _eflags;
diff --git a/com32/include/syslinux/pxe.h b/com32/include/syslinux/pxe.h
index 037642bc..6e2a769b 100644
--- a/com32/include/syslinux/pxe.h
+++ b/com32/include/syslinux/pxe.h
@@ -37,6 +37,7 @@
#include <stdint.h>
#include <netinet/in.h>
#include <klibc/compiler.h>
+#include <com32.h>
/* PXE spec structures and definitions. These mostly follow the PXE
spec, except when the PXE spec is unnecessarily stupid. Of course,
@@ -57,10 +58,7 @@ typedef struct {
uint16_t segsize;
} __packed pxe_segdesc_t;
-typedef struct {
- uint16_t offs;
- uint16_t seg;
-} segoff16_t;
+typedef far_ptr_t segoff16_t;
typedef struct {
uint8_t opcode;
@@ -522,5 +520,6 @@ typedef struct s_PXENV_UNDI_ISR {
/* SYSLINUX-defined PXE utility functions */
int pxe_get_cached_info(int level, void **buf, size_t * len);
int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE * gnt);
+uint32_t pxe_dns(const char *hostname);
#endif /* _SYSLINUX_PXE_H */
diff --git a/com32/include/syslinux/video.h b/com32/include/syslinux/video.h
index 737c742b..f22828aa 100644
--- a/com32/include/syslinux/video.h
+++ b/com32/include/syslinux/video.h
@@ -37,7 +37,7 @@
#include <stdint.h>
void syslinux_force_text_mode(void);
-int syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize);
-int syslinux_font_query(void **font);
+void syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize);
+int syslinux_font_query(uint8_t **font);
#endif /* _SYSLINUX_API_H */
diff --git a/com32/lib/MCONFIG b/com32/lib/MCONFIG
index 1eb18db1..1ae83bc7 100644
--- a/com32/lib/MCONFIG
+++ b/com32/lib/MCONFIG
@@ -24,7 +24,7 @@ REQFLAGS = $(GCCOPT) -g -mregparm=3 -DREGPARM=3 -D__COM32__ \
-nostdinc -iwithprefix include -I. -I./sys -I../include
OPTFLAGS = -Os -march=i386 -falign-functions=0 -falign-jumps=0 \
-falign-labels=0 -ffast-math -fomit-frame-pointer
-WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline
+WARNFLAGS = $(GCCWARN) -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline
CFLAGS = $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) $(LIBFLAGS)
LDFLAGS = -m elf32_i386
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index ad77bcd6..250c3962 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -64,10 +64,11 @@ LIBOBJS = \
sys/vesacon_write.o sys/vesaserial_write.o \
sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \
sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o \
+ sys/vesa/i915resolution.o \
\
- pci/cfgtype.o pci/scan.o \
- pci/readb.o pci/readw.o pci/readl.o pci/readbios.o \
- pci/writeb.o pci/writew.o pci/writel.o pci/writebios.o \
+ pci/cfgtype.o pci/scan.o pci/bios.o \
+ pci/readb.o pci/readw.o pci/readl.o \
+ pci/writeb.o pci/writew.o pci/writel.o \
\
zlib/adler32.o zlib/compress.o zlib/crc32.o \
zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \
@@ -108,9 +109,13 @@ LIBOBJS = \
syslinux/initramfs_archive.o \
\
syslinux/pxe_get_cached.o syslinux/pxe_get_nic.o \
+ syslinux/pxe_dns.o \
\
syslinux/adv.o syslinux/advwrite.o syslinux/getadv.o \
- syslinux/setadv.o
+ syslinux/setadv.o \
+ \
+ syslinux/video/fontquery.o syslinux/video/forcetext.o \
+ syslinux/video/reportmode.o
BINDIR = /usr/bin
LIBDIR = /usr/lib
diff --git a/com32/lib/chdir.c b/com32/lib/chdir.c
index 6f92d668..6a365f3b 100644
--- a/com32/lib/chdir.c
+++ b/com32/lib/chdir.c
@@ -8,6 +8,10 @@
int chdir(const char *path)
{
+ /* Actually implement something here... */
+
+ (void)path;
+
errno = ENOSYS;
return -1;
}
diff --git a/com32/lib/closedir.c b/com32/lib/closedir.c
index f8bbbabd..a2d11105 100644
--- a/com32/lib/closedir.c
+++ b/com32/lib/closedir.c
@@ -10,6 +10,7 @@
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
+#include <stdlib.h>
int closedir(DIR * dir)
{
diff --git a/com32/lib/fdopendir.c b/com32/lib/fdopendir.c
index 5fe11617..4fc31388 100644
--- a/com32/lib/fdopendir.c
+++ b/com32/lib/fdopendir.c
@@ -8,6 +8,8 @@
DIR *fdopendir(int __fd)
{
+ (void)__fd;
+
errno = ENOSYS;
return NULL;
}
diff --git a/com32/lib/libgcc/__moddi3.c b/com32/lib/libgcc/__moddi3.c
index ac8d3af7..4fc55884 100644
--- a/com32/lib/libgcc/__moddi3.c
+++ b/com32/lib/libgcc/__moddi3.c
@@ -21,7 +21,7 @@ int64_t __moddi3(int64_t num, int64_t den)
minus ^= 1;
}
- (void)__udivmoddi4(num, den, &v);
+ (void)__udivmoddi4(num, den, (uint64_t *)&v);
if (minus)
v = -v;
diff --git a/com32/lib/opendir.c b/com32/lib/opendir.c
index 6fc0f14f..21fe91d4 100644
--- a/com32/lib/opendir.c
+++ b/com32/lib/opendir.c
@@ -10,6 +10,7 @@
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
+#include <stdlib.h>
DIR *opendir(const char *pathname)
{
diff --git a/com32/lib/pci/readbios.c b/com32/lib/pci/bios.c
index f8ff3bff..b3c2c57d 100644
--- a/com32/lib/pci/readbios.c
+++ b/com32/lib/pci/bios.c
@@ -2,13 +2,15 @@
#include <string.h>
#include "pci/pci.h"
-uint32_t __pci_read_bios(uint32_t call, pciaddr_t a)
+uint32_t __pci_read_write_bios(uint32_t call, uint32_t v, pciaddr_t a)
{
com32sys_t rs;
memset(&rs, 0, sizeof rs);
rs.eax.w[0] = call;
rs.ebx.w[0] = a >> 8; /* bus:device:function */
rs.edi.b[0] = a; /* address:reg */
+ rs.ecx.l = v;
+ rs.eflags.l = EFLAGS_CF;
__intcall(0x1a, &rs, &rs);
return (rs.eflags.l & EFLAGS_CF) ? ~(uint32_t) 0 : rs.ecx.l;
diff --git a/com32/lib/pci/pci.h b/com32/lib/pci/pci.h
index 66a1eb50..8d81b0e4 100644
--- a/com32/lib/pci/pci.h
+++ b/com32/lib/pci/pci.h
@@ -10,7 +10,6 @@
#include <sys/cpu.h>
extern enum pci_config_type __pci_cfg_type;
-extern uint32_t __pci_read_bios(uint32_t call, pciaddr_t a);
-extern void __pci_write_bios(uint32_t call, uint32_t v, pciaddr_t a);
+extern uint32_t __pci_read_write_bios(uint32_t call, uint32_t v, pciaddr_t a);
#endif /* PCI_PCI_H */
diff --git a/com32/lib/pci/readx.c b/com32/lib/pci/readx.c
index f073eaa1..ed66d5b2 100644
--- a/com32/lib/pci/readx.c
+++ b/com32/lib/pci/readx.c
@@ -1,7 +1,7 @@
#include "pci/pci.h"
-#include <string.h>
-TYPE BWL(pci_read) (pciaddr_t a) {
+TYPE BWL(pci_read) (pciaddr_t a)
+{
TYPE r;
for (;;) {
@@ -42,7 +42,7 @@ TYPE BWL(pci_read) (pciaddr_t a) {
return r;
case PCI_CFG_BIOS:
- return (TYPE) __pci_read_bios(BIOSCALL, a);
+ return (TYPE) __pci_read_write_bios(BIOSCALL, 0, a);
default:
return (TYPE) ~ 0;
diff --git a/com32/lib/pci/writebios.c b/com32/lib/pci/writebios.c
deleted file mode 100644
index d367eee7..00000000
--- a/com32/lib/pci/writebios.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <com32.h>
-#include <string.h>
-#include "pci/pci.h"
-
-void __pci_write_bios(uint32_t call, uint32_t v, pciaddr_t a)
-{
- com32sys_t rs;
- memset(&rs, 0, sizeof rs);
- rs.eax.w[0] = call;
- rs.ebx.w[0] = a >> 8; /* bus:device:function */
- rs.edi.b[0] = a; /* address:reg */
- rs.ecx.l = v;
- __intcall(0x1a, &rs, NULL);
-}
diff --git a/com32/lib/pci/writex.c b/com32/lib/pci/writex.c
index 14b20380..d83a1eed 100644
--- a/com32/lib/pci/writex.c
+++ b/com32/lib/pci/writex.c
@@ -1,6 +1,7 @@
#include "pci/pci.h"
-void BWL(pci_write) (TYPE v, pciaddr_t a) {
+void BWL(pci_write)(TYPE v, pciaddr_t a)
+{
for (;;) {
switch (__pci_cfg_type) {
case PCI_CFG_AUTO:
@@ -39,7 +40,7 @@ void BWL(pci_write) (TYPE v, pciaddr_t a) {
return;
case PCI_CFG_BIOS:
- __pci_write_bios(BIOSCALL, v, a);
+ __pci_read_write_bios(BIOSCALL, v, a);
return;
default:
diff --git a/com32/lib/readdir.c b/com32/lib/readdir.c
index 2ec7c7b3..3737d1ad 100644
--- a/com32/lib/readdir.c
+++ b/com32/lib/readdir.c
@@ -10,6 +10,7 @@
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
+#include <stdlib.h>
struct dirent *readdir(DIR * dir)
{
@@ -28,8 +29,10 @@ struct dirent *readdir(DIR * dir)
__com32.cs_intcall(0x22, &regs, &regs);
- /* Don't do this as we won't be able to rewind.
+#if 0
+ /* Don't do this as we won't be able to rewind. */
dir->dd_fd = regs.esi.w[0]; /* Shouldn't be needed? */
+#endif
if ((!(regs.eflags.l & EFLAGS_CF)) && (regs.esi.w[0] != 0)) {
newde = calloc(1, sizeof(newde));
if (newde != NULL) {
diff --git a/com32/lib/strcasecmp.c b/com32/lib/strcasecmp.c
index 849c21fd..30949a09 100644
--- a/com32/lib/strcasecmp.c
+++ b/com32/lib/strcasecmp.c
@@ -7,7 +7,8 @@
int strcasecmp(const char *s1, const char *s2)
{
- const unsigned char *c1 = s1, *c2 = s2;
+ const unsigned char *c1 = (const unsigned char *)s1;
+ const unsigned char *c2 = (const unsigned char *)s2;
unsigned char ch;
int d = 0;
diff --git a/com32/lib/strcmp.c b/com32/lib/strcmp.c
index 77bb2b41..47a4aad8 100644
--- a/com32/lib/strcmp.c
+++ b/com32/lib/strcmp.c
@@ -6,7 +6,8 @@
int strcmp(const char *s1, const char *s2)
{
- const unsigned char *c1 = s1, *c2 = s2;
+ const unsigned char *c1 = (const unsigned char *)s1;
+ const unsigned char *c2 = (const unsigned char *)s2;
unsigned char ch;
int d = 0;
diff --git a/com32/lib/strncasecmp.c b/com32/lib/strncasecmp.c
index 8b8b967a..2caac0a5 100644
--- a/com32/lib/strncasecmp.c
+++ b/com32/lib/strncasecmp.c
@@ -7,7 +7,8 @@
int strncasecmp(const char *s1, const char *s2, size_t n)
{
- const unsigned char *c1 = s1, *c2 = s2;
+ const unsigned char *c1 = (const unsigned char *)s1;
+ const unsigned char *c2 = (const unsigned char *)s2;
unsigned char ch;
int d = 0;
diff --git a/com32/lib/strncmp.c b/com32/lib/strncmp.c
index f2f2f022..e41b9e36 100644
--- a/com32/lib/strncmp.c
+++ b/com32/lib/strncmp.c
@@ -6,7 +6,8 @@
int strncmp(const char *s1, const char *s2, size_t n)
{
- const unsigned char *c1 = s1, *c2 = s2;
+ const unsigned char *c1 = (const unsigned char *)s1;
+ const unsigned char *c2 = (const unsigned char *)s2;
unsigned char ch;
int d = 0;
diff --git a/com32/lib/sys/argv.c b/com32/lib/sys/argv.c
index b325f26d..3ff869b7 100644
--- a/com32/lib/sys/argv.c
+++ b/com32/lib/sys/argv.c
@@ -37,13 +37,14 @@
#include <stddef.h>
#include <stdio.h>
#include <syslinux/align.h>
+#include <com32.h>
extern char _end[]; /* Symbol created by linker */
void *__mem_end = &_end; /* Global variable for use by malloc() */
int __parse_argv(char ***argv, const char *str)
{
- char argv0[] = "";
+ char dummy_argv0[] = "";
char *mem = __mem_end;
const char *p = str;
char *q = mem;
@@ -75,9 +76,9 @@ int __parse_argv(char ***argv, const char *str)
}
/* Now create argv */
- arg = ALIGN_UP_FOR(q, char *);
+ arg = (char **)ALIGN_UP_FOR(q, char *);
*argv = arg;
- *arg++ = argv0; /* argv[0] */
+ *arg++ = __com32.cs_name ? __com32.cs_name : dummy_argv0; /* argv[0] */
q--; /* Point q to final null */
if (mem < q)
diff --git a/com32/lib/sys/colortable.c b/com32/lib/sys/colortable.c
index df6d9782..ab1c4246 100644
--- a/com32/lib/sys/colortable.c
+++ b/com32/lib/sys/colortable.c
@@ -4,6 +4,6 @@ static struct color_table default_color_table[] = {
{"default", "0", 0xffffffff, 0x00000000, SHADOW_NORMAL}
};
-struct color_table *console_color_table = &default_color_table;
+struct color_table *console_color_table = default_color_table;
int console_color_table_size =
(sizeof default_color_table / sizeof(struct color_table));
diff --git a/com32/lib/sys/entry.S b/com32/lib/sys/entry.S
index 53bf2ecb..c34dbdf4 100644
--- a/com32/lib/sys/entry.S
+++ b/com32/lib/sys/entry.S
@@ -30,7 +30,7 @@
*/
/* Number of arguments in our version of the entry structure */
-#define COM32_ARGS 7
+#define COM32_ARGS 8
.section ".init","ax"
.globl _start
diff --git a/com32/lib/sys/libansi.c b/com32/lib/sys/libansi.c
index 5bc0026e..a011cb87 100644
--- a/com32/lib/sys/libansi.c
+++ b/com32/lib/sys/libansi.c
@@ -46,18 +46,21 @@ void display_cursor(bool status)
}
}
-void clear_end_of_line() {
+void clear_end_of_line(void)
+{
fputs(CSI "0K", stdout);
}
-void move_cursor_left(int count) {
+void move_cursor_left(int count)
+{
char buffer[10];
memset(buffer,0,sizeof(buffer));
sprintf(buffer,CSI "%dD",count);
fputs(buffer, stdout);
}
-void move_cursor_right(int count) {
+void move_cursor_right(int count)
+{
char buffer[10];
memset(buffer,0,sizeof(buffer));
sprintf(buffer, CSI "%dC", count);
@@ -71,38 +74,45 @@ void set_cursor_blink(bool status) {
fputs("\033[0m",stdout);
}
-void clear_line() {
+void clear_line(void)
+{
fputs(CSI "2K", stdout);
}
-void clear_beginning_of_line() {
+void clear_beginning_of_line(void)
+{
fputs(CSI "1K", stdout);
}
-void move_cursor_to_column(int count) {
+void move_cursor_to_column(int count)
+{
char buffer[10];
memset(buffer,0,sizeof(buffer));
sprintf(buffer, CSI "%dG", count);
fputs(buffer, stdout);
}
-void move_cursor_to_next_line() {
+void move_cursor_to_next_line(void)
+{
fputs("\033e", stdout);
}
-void disable_utf8() {
+void disable_utf8(void)
+{
fputs("\033%@", stdout);
}
-void set_g1_special_char(){
+void set_g1_special_char(void){
fputs("\033)0", stdout);
}
-void set_us_g0_charset() {
+void set_us_g0_charset(void)
+{
fputs("\033(B\1#0", stdout);
}
-void clear_entire_screen() {
+void clear_entire_screen(void)
+{
fputs(CSI "2J", stdout);
}
@@ -186,7 +196,7 @@ void cls(void)
cprint_vga2ansi('0', '0');
}
-void reset_colors()
+void reset_colors(void)
{
csprint(CSI "1D", 0x07);
}
diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c
index 256c8247..8d732395 100644
--- a/com32/lib/sys/vesa/background.c
+++ b/com32/lib/sys/vesa/background.c
@@ -75,26 +75,54 @@ static void draw_background(void)
__vesacon_redraw_text();
}
+/*
+ * Tile an image in the UL corner across the entire screen
+ */
+static void tile_image(int width, int height)
+{
+ int xsize = __vesa_info.mi.h_res;
+ int ysize = __vesa_info.mi.v_res;
+ int x, y, yr;
+ int xl, yl;
+ uint32_t *sp, *dp, *drp, *dtp;
+
+ drp = __vesacon_background;
+ for (y = 0 ; y < ysize ; y += height) {
+ yl = min(height, ysize-y);
+ dtp = drp;
+ for (x = 0 ; x < xsize ; x += width) {
+ xl = min(width, xsize-x);
+ if (x || y) {
+ sp = __vesacon_background;
+ dp = dtp;
+ for (yr = 0 ; yr < yl ; yr++) {
+ memcpy(dp, sp, xl*sizeof(uint32_t));
+ dp += xsize;
+ sp += xsize;
+ }
+ }
+ dtp += xl;
+ }
+ drp += xsize*height;
+ }
+}
+
static int read_png_file(FILE * fp)
{
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
- png_infop end_ptr = NULL;
#if 0
png_color_16p image_background;
static const png_color_16 my_background = { 0, 0, 0, 0, 0 };
#endif
png_bytep row_pointers[__vesa_info.mi.v_res], rp;
- int passes;
int i;
int rv = -1;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
info_ptr = png_create_info_struct(png_ptr);
- end_ptr = png_create_info_struct(png_ptr);
- if (!png_ptr || !info_ptr || !end_ptr || setjmp(png_jmpbuf(png_ptr)))
+ if (!png_ptr || !info_ptr || setjmp(png_jmpbuf(png_ptr)))
goto err;
png_init_io(png_ptr, fp);
@@ -146,16 +174,15 @@ static int read_png_file(FILE * fp)
rp += __vesa_info.mi.h_res << 2;
}
- passes = png_set_interlace_handling(png_ptr);
+ png_read_image(png_ptr, row_pointers);
- for (i = 0; i < passes; i++)
- png_read_rows(png_ptr, row_pointers, NULL, info_ptr->height);
+ tile_image(info_ptr->width, info_ptr->height);
rv = 0;
err:
if (png_ptr)
- png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
return rv;
}
@@ -198,6 +225,7 @@ static int read_jpeg_file(FILE * fp, uint8_t * header, int len)
tinyjpeg_set_bytes_per_row(jdec, bytes_per_row, 1);
tinyjpeg_decode(jdec, TINYJPEG_FMT_BGRA32);
+ tile_image(width, height);
rv = 0;
@@ -217,18 +245,25 @@ err:
int vesacon_default_background(void)
{
int x, y, dx, dy, dy2;
- uint8_t *bgptr = (uint8_t *) & __vesacon_background;
+ int z;
+ unsigned int shft;
+ uint8_t *bgptr = (uint8_t *)__vesacon_background;
uint8_t k;
if (__vesacon_pixel_format == PXF_NONE)
return 0; /* Not in graphics mode */
- for (y = 0, dy = -__vesa_info.mi.v_res / 2;
+ z = max(__vesa_info.mi.v_res, __vesa_info.mi.h_res) >> 1;
+ z = ((z*z) >> 11) - 1;
+ asm("bsrl %1,%0" : "=r" (shft) : "rm" (z));
+ shft++;
+
+ for (y = 0, dy = -(__vesa_info.mi.v_res >> 1);
y < __vesa_info.mi.v_res; y++, dy++) {
dy2 = dy * dy;
- for (x = 0, dx = -__vesa_info.mi.h_res / 2;
+ for (x = 0, dx = -(__vesa_info.mi.h_res >> 1);
x < __vesa_info.mi.h_res; x++, dx++) {
- k = __vesacon_linear_to_srgb[500 + ((dx * dx + dy2) >> 6)];
+ k = __vesacon_linear_to_srgb[500 + ((dx*dx + dy2) >> shft)];
bgptr[0] = k; /* Blue */
bgptr[1] = k; /* Green */
bgptr[2] = k; /* Red */
diff --git a/com32/lib/sys/vesa/i915resolution.c b/com32/lib/sys/vesa/i915resolution.c
new file mode 100644
index 00000000..6ebb04d3
--- /dev/null
+++ b/com32/lib/sys/vesa/i915resolution.c
@@ -0,0 +1,795 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Based on:
+ *
+ * 915 resolution by steve tomljenovic
+ *
+ * This was tested only on Sony VGN-FS550. Use at your own risk
+ *
+ * This code is based on the techniques used in :
+ *
+ * - 855patch. Many thanks to Christian Zietz (czietz gmx net)
+ * for demonstrating how to shadow the VBIOS into system RAM
+ * and then modify it.
+ *
+ * - 1280patch by Andrew Tipton (andrewtipton null li).
+ *
+ * - 855resolution by Alain Poirier
+ *
+ * This source code is into the public domain.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#define __USE_GNU
+#include <string.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+#include <sys/pci.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdbool.h>
+#include "video.h"
+#include "debug.h"
+
+#define VBIOS_START 0xc0000
+#define VBIOS_SIZE 0x10000
+
+#define MODE_TABLE_OFFSET_845G 617
+
+#define VERSION "0.5.3"
+
+#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
+#define ATI_SIGNATURE2 "ATI Technologies Inc"
+#define NVIDIA_SIGNATURE "NVIDIA Corp"
+#define INTEL_SIGNATURE "Intel Corp"
+
+typedef unsigned char * address;
+
+typedef enum {
+ CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM,
+ CT_945G, CT_945GM, CT_946GZ, CT_G965, CT_Q965, CT_945GME,
+ CHIPSET_TYPES
+} chipset_type;
+
+typedef enum {
+ BT_UNKWN, BT_1, BT_2, BT_3
+} bios_type;
+
+static int freqs[] = { 60, 75, 85 };
+
+typedef struct {
+ uint8_t mode;
+ uint8_t bits_per_pixel;
+ uint16_t resolution;
+ uint8_t unknown;
+} __attribute__((packed)) vbios_mode;
+
+typedef struct {
+ uint16_t clock; /* Clock frequency in 10 kHz */
+ uint8_t x1;
+ uint8_t x_total;
+ uint8_t x2;
+ uint8_t y1;
+ uint8_t y_total;
+ uint8_t y2;
+} __attribute__((packed)) vbios_resolution_type1;
+
+typedef struct {
+ uint32_t clock;
+
+ uint16_t x1;
+ uint16_t htotal;
+ uint16_t x2;
+ uint16_t hblank;
+ uint16_t hsyncstart;
+ uint16_t hsyncend;
+
+ uint16_t y1;
+ uint16_t vtotal;
+ uint16_t y2;
+ uint16_t vblank;
+ uint16_t vsyncstart;
+ uint16_t vsyncend;
+} __attribute__((packed)) vbios_modeline_type2;
+
+typedef struct {
+ uint8_t xchars;
+ uint8_t ychars;
+ uint8_t unknown[4];
+
+ vbios_modeline_type2 modelines[];
+} __attribute__((packed)) vbios_resolution_type2;
+
+typedef struct {
+ uint32_t clock;
+
+ uint16_t x1;
+ uint16_t htotal;
+ uint16_t x2;
+ uint16_t hblank;
+ uint16_t hsyncstart;
+ uint16_t hsyncend;
+
+ uint16_t y1;
+ uint16_t vtotal;
+ uint16_t y2;
+ uint16_t vblank;
+ uint16_t vsyncstart;
+ uint16_t vsyncend;
+
+ uint16_t timing_h;
+ uint16_t timing_v;
+
+ uint8_t unknown[6];
+} __attribute__((packed)) vbios_modeline_type3;
+
+typedef struct {
+ unsigned char unknown[6];
+
+ vbios_modeline_type3 modelines[];
+} __attribute__((packed)) vbios_resolution_type3;
+
+
+typedef struct {
+ unsigned int chipset_id;
+ chipset_type chipset;
+ bios_type bios;
+
+ address bios_ptr;
+
+ vbios_mode * mode_table;
+ unsigned int mode_table_size;
+
+ uint8_t b1, b2;
+
+ bool unlocked;
+} vbios_map;
+
+#if 0 /* Debugging hacks */
+static void good_marker(int x)
+{
+ ((uint16_t *)0xb8000)[x] = 0x2f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void bad_marker(int x)
+{
+ ((uint16_t *)0xb8000)[x] = 0x4f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void status(const char *fmt, ...)
+{
+ va_list ap;
+ char msg[81], *p;
+ int i;
+ uint16_t *q;
+
+ memset(msg, 0, sizeof msg);
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof msg, fmt, ap);
+ va_end(ap);
+ p = msg;
+ q = (uint16_t *)0xb8000 + 80;
+ for (i = 0; i < 80; i++)
+ *q++ = *p++ + 0x1f00;
+}
+#else
+static inline void good_marker(int x) { (void)x; }
+static inline void bad_marker(int x) { (void)x; }
+static inline void status(const char *fmt, ...) { (void)fmt; }
+#endif
+
+static unsigned int get_chipset_id(void) {
+ return pci_readl(0x80000000);
+}
+
+static chipset_type get_chipset(unsigned int id) {
+ chipset_type type;
+
+ switch (id) {
+ case 0x35758086:
+ type = CT_830;
+ break;
+
+ case 0x25608086:
+ type = CT_845G;
+ break;
+
+ case 0x35808086:
+ type = CT_855GM;
+ break;
+
+ case 0x25708086:
+ type = CT_865G;
+ break;
+
+ case 0x25808086:
+ type = CT_915G;
+ break;
+
+ case 0x25908086:
+ type = CT_915GM;
+ break;
+
+ case 0x27708086:
+ type = CT_945G;
+ break;
+
+ case 0x27a08086:
+ type = CT_945GM;
+ break;
+
+ case 0x29708086:
+ type = CT_946GZ;
+ break;
+
+ case 0x29a08086:
+ type = CT_G965;
+ break;
+
+ case 0x29908086:
+ type = CT_Q965;
+ break;
+
+ case 0x27ac8086:
+ type = CT_945GME;
+ break;
+
+ default:
+ type = CT_UNKWN;
+ break;
+ }
+
+ return type;
+}
+
+
+static vbios_resolution_type1 * map_type1_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
+ return ptr;
+}
+
+static vbios_resolution_type2 * map_type2_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
+ return ptr;
+}
+
+static vbios_resolution_type3 * map_type3_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
+ return ptr;
+}
+
+
+static bool detect_bios_type(vbios_map * map, int entry_size)
+{
+ unsigned int i;
+ uint16_t r1, r2;
+
+ r1 = r2 = 32000;
+
+ for (i = 0; i < map->mode_table_size; i++) {
+ if (map->mode_table[i].resolution <= r1) {
+ r1 = map->mode_table[i].resolution;
+ } else if (map->mode_table[i].resolution <= r2) {
+ r2 = map->mode_table[i].resolution;
+ }
+ }
+
+ return ((r2-r1-6) % entry_size) == 0;
+}
+
+static inline void close_vbios(vbios_map *map)
+{
+ (void)map;
+}
+
+static vbios_map * open_vbios(void)
+{
+ static vbios_map _map;
+ vbios_map * const map = &_map;
+
+ memset(&_map, 0, sizeof _map);
+
+ /*
+ * Determine chipset
+ */
+ map->chipset_id = get_chipset_id();
+ good_marker(0x10);
+ map->chipset = get_chipset(map->chipset_id);
+ good_marker(0x11);
+
+ /*
+ * Map the video bios to memory
+ */
+ map->bios_ptr = (void *)VBIOS_START;
+
+ /*
+ * check if we have ATI Radeon
+ */
+
+ if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) ||
+ memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) {
+ debug("ATI chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+ return NULL;
+ }
+
+ /*
+ * check if we have NVIDIA
+ */
+
+ if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) {
+ debug("NVIDIA chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+ return NULL;
+ }
+
+ /*
+ * check if we have Intel
+ */
+
+ if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
+ debug("Intel chipset detected. However, 915resolution was unable to determine the chipset type.\r\n");
+
+ debug("Chipset Id: %x\r\n", map->chipset_id);
+
+ debug("Please report this problem to stomljen@yahoo.com\r\n");
+
+ close_vbios(map);
+ return NULL;
+ }
+
+ /*
+ * check for others
+ */
+
+ if (map->chipset == CT_UNKWN) {
+ debug("Unknown chipset type and unrecognized bios.\r\n");
+ debug("915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+
+ debug("Chipset Id: %x\r\n", map->chipset_id);
+ close_vbios(map);
+ return NULL;
+ }
+
+ /*
+ * Figure out where the mode table is
+ */
+ good_marker(0x12);
+
+ {
+ address p = map->bios_ptr + 16;
+ address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
+
+ while (p < limit && map->mode_table == 0) {
+ vbios_mode * mode_ptr = (vbios_mode *) p;
+
+ if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
+ ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
+
+ map->mode_table = mode_ptr;
+ }
+
+ p++;
+ }
+
+ if (map->mode_table == 0) {
+ debug("Unable to locate the mode table.\r\n");
+ close_vbios(map);
+ return NULL;
+ }
+ }
+ good_marker(0x13);
+
+ /*
+ * Determine size of mode table
+ */
+
+ {
+ vbios_mode * mode_ptr = map->mode_table;
+
+ while (mode_ptr->mode != 0xff) {
+ map->mode_table_size++;
+ mode_ptr++;
+ }
+ }
+ good_marker(0x14);
+ status("mode_table_size = %d", map->mode_table_size);
+
+ /*
+ * Figure out what type of bios we have
+ * order of detection is important
+ */
+
+ if (detect_bios_type(map, sizeof(vbios_modeline_type3))) {
+ map->bios = BT_3;
+ }
+ else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) {
+ map->bios = BT_2;
+ }
+ else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) {
+ map->bios = BT_1;
+ }
+ else {
+ debug("Unable to determine bios type.\r\n");
+ debug("Mode Table Offset: $C0000 + $%x\r\n", ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+ debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+ bad_marker(0x15);
+ return NULL;
+ }
+ good_marker(0x15);
+
+ return map;
+}
+
+static void unlock_vbios(vbios_map * map)
+{
+ assert(!map->unlocked);
+
+ map->unlocked = true;
+
+ switch (map->chipset) {
+ case CT_UNKWN:
+ case CHIPSET_TYPES: /* Shut up gcc */
+ break;
+ case CT_830:
+ case CT_855GM:
+ map->b1 = pci_readb(0x8000005a);
+ pci_writeb(0x33, 0x8000005a);
+ break;
+ case CT_845G:
+ case CT_865G:
+ case CT_915G:
+ case CT_915GM:
+ case CT_945G:
+ case CT_945GM:
+ case CT_945GME:
+ case CT_946GZ:
+ case CT_G965:
+ case CT_Q965:
+ map->b1 = pci_readb(0x80000091);
+ map->b2 = pci_readb(0x80000092);
+ pci_writeb(0x33, 0x80000091);
+ pci_writeb(0x33, 0x80000092);
+ break;
+ }
+
+#if DEBUG
+ {
+ unsigned int t = inl(0xcfc);
+ debug("unlock PAM: (0x%08x)\r\n", t);
+ }
+#endif
+}
+
+static void relock_vbios(vbios_map * map)
+{
+ assert(map->unlocked);
+ map->unlocked = false;
+
+ switch (map->chipset) {
+ case CT_UNKWN:
+ case CHIPSET_TYPES: /* Shut up gcc */
+ break;
+ case CT_830:
+ case CT_855GM:
+ pci_writeb(map->b1, 0x8000005a);
+ break;
+ case CT_845G:
+ case CT_865G:
+ case CT_915G:
+ case CT_915GM:
+ case CT_945G:
+ case CT_945GM:
+ case CT_945GME:
+ case CT_946GZ:
+ case CT_G965:
+ case CT_Q965:
+ pci_writeb(map->b1, 0x80000091);
+ pci_writeb(map->b2, 0x80000092);
+ break;
+ }
+
+#if DEBUG
+ {
+ unsigned int t = inl(0xcfc);
+ debug("relock PAM: (0x%08x)\r\n", t);
+ }
+#endif
+}
+
+#if 0
+static void list_modes(vbios_map *map, unsigned int raw)
+{
+ unsigned int i, x, y;
+
+ for (i=0; i < map->mode_table_size; i++) {
+ switch(map->bios) {
+ case BT_1:
+ {
+ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+
+ x = ((((unsigned int) res->x2) & 0xf0) << 4) | res->x1;
+ y = ((((unsigned int) res->y2) & 0xf0) << 4) | res->y1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+
+ if (raw)
+ {
+ debug("Mode %02x (raw) :\r\n\t%02x %02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
+ }
+
+ }
+ break;
+ case BT_2:
+ {
+ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+
+ x = res->modelines[0].x1+1;
+ y = res->modelines[0].y1+1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+ }
+ break;
+ case BT_3:
+ {
+ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+
+ x = res->modelines[0].x1+1;
+ y = res->modelines[0].y1+1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+ }
+ break;
+ case BT_UNKWN:
+ break;
+ }
+ }
+}
+#endif
+
+static void gtf_timings(int x, int y, int freq, uint32_t *clock,
+ uint16_t *hsyncstart, uint16_t *hsyncend, uint16_t *hblank,
+ uint16_t *vsyncstart, uint16_t *vsyncend, uint16_t *vblank)
+{
+ int hbl, vbl, vfreq;
+
+ vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
+ vfreq = vbl * freq;
+ hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
+ (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
+
+ *vsyncstart = y;
+ *vsyncend = y + 3;
+ *vblank = vbl - 1;
+ *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
+ *hsyncend = x + hbl / 2 - 1;
+ *hblank = x + hbl - 1;
+ *clock = (x + hbl) * vfreq / 1000;
+}
+
+static int set_mode(vbios_map * map, unsigned int mode,
+ unsigned int x, unsigned int y, unsigned int bp,
+ unsigned int htotal, unsigned int vtotal)
+{
+ int xprev, yprev;
+ unsigned int i, j;
+ int rv = -1;
+
+ for (i=0; i < map->mode_table_size; i++) {
+ if (map->mode_table[i].mode == mode) {
+ switch(map->bios) {
+ case BT_1:
+ {
+ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+ uint32_t clock;
+ uint16_t hsyncstart, hsyncend, hblank;
+ uint16_t vsyncstart, vsyncend, vblank;
+
+ if (bp) {
+ map->mode_table[i].bits_per_pixel = bp;
+ }
+
+ gtf_timings(x, y, freqs[0], &clock,
+ &hsyncstart, &hsyncend, &hblank,
+ &vsyncstart, &vsyncend, &vblank);
+
+ status("x = %d, y = %d, clock = %lu, h = %d %d %d, v = %d %d %d\n",
+ x, y, clock,
+ hsyncstart, hsyncend, hblank,
+ vsyncstart, vsyncend, vblank);
+
+ htotal = htotal ? htotal : (unsigned int)hblank+1;
+ vtotal = vtotal ? vtotal : (unsigned int)vblank+1;
+
+ res->clock = clock/10; /* Units appear to be 10 kHz */
+ res->x2 = (((htotal-x) >> 8) & 0x0f) | ((x >> 4) & 0xf0);
+ res->x1 = (x & 0xff);
+
+ res->y2 = (((vtotal-y) >> 8) & 0x0f) | ((y >> 4) & 0xf0);
+ res->y1 = (y & 0xff);
+ if (htotal)
+ res->x_total = ((htotal-x) & 0xff);
+
+ if (vtotal)
+ res->y_total = ((vtotal-y) & 0xff);
+
+ rv = 0;
+ }
+ break;
+ case BT_2:
+ {
+ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+
+ res->xchars = x / 8;
+ res->ychars = y / 16 - 1;
+ xprev = res->modelines[0].x1;
+ yprev = res->modelines[0].y1;
+
+ for(j=0; j < 3; j++) {
+ vbios_modeline_type2 * modeline = &res->modelines[j];
+
+ if (modeline->x1 == xprev && modeline->y1 == yprev) {
+ modeline->x1 = modeline->x2 = x-1;
+ modeline->y1 = modeline->y2 = y-1;
+
+ gtf_timings(x, y, freqs[j], &modeline->clock,
+ &modeline->hsyncstart, &modeline->hsyncend,
+ &modeline->hblank, &modeline->vsyncstart,
+ &modeline->vsyncend, &modeline->vblank);
+
+ if (htotal)
+ modeline->htotal = htotal;
+ else
+ modeline->htotal = modeline->hblank;
+
+ if (vtotal)
+ modeline->vtotal = vtotal;
+ else
+ modeline->vtotal = modeline->vblank;
+ }
+ }
+
+ rv = 0;
+ }
+ break;
+ case BT_3:
+ {
+ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+
+ xprev = res->modelines[0].x1;
+ yprev = res->modelines[0].y1;
+
+ for (j=0; j < 3; j++) {
+ vbios_modeline_type3 * modeline = &res->modelines[j];
+
+ if (modeline->x1 == xprev && modeline->y1 == yprev) {
+ modeline->x1 = modeline->x2 = x-1;
+ modeline->y1 = modeline->y2 = y-1;
+
+ gtf_timings(x, y, freqs[j], &modeline->clock,
+ &modeline->hsyncstart, &modeline->hsyncend,
+ &modeline->hblank, &modeline->vsyncstart,
+ &modeline->vsyncend, &modeline->vblank);
+ if (htotal)
+ modeline->htotal = htotal;
+ else
+ modeline->htotal = modeline->hblank;
+ if (vtotal)
+ modeline->vtotal = vtotal;
+ else
+ modeline->vtotal = modeline->vblank;
+
+ modeline->timing_h = y-1;
+ modeline->timing_v = x-1;
+ }
+ }
+
+ rv = 0;
+ }
+ break;
+ case BT_UNKWN:
+ break;
+ }
+ }
+ }
+
+ return rv;
+}
+
+static inline void display_map_info(vbios_map * map) {
+#ifdef DEBUG
+ static const char * bios_type_names[] =
+ {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
+ static const char * chipset_type_names[] = {
+ "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G",
+ "945GM", "946GZ", "G965", "Q965", "945GME"
+ };
+
+ debug("Chipset: %s\r\n", chipset_type_names[map->chipset]);
+ debug("BIOS: %s\r\n", bios_type_names[map->bios]);
+
+ debug("Mode Table Offset: $C0000 + $%x\r\n",
+ ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+ debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+#endif
+ (void)map;
+}
+
+int __vesacon_i915resolution(int x, int y)
+{
+ vbios_map * map;
+ unsigned int mode = 0x52; /* 800x600x32 mode in known BIOSes */
+ unsigned int bp = 32; /* 32 bits per pixel */
+ int rv = 0;
+
+ good_marker(0);
+
+ map = open_vbios();
+ if (!map)
+ return -1;
+
+ good_marker(1);
+
+ display_map_info(map);
+
+ debug("\r\n");
+
+ if (mode && x && y) {
+ good_marker(2);
+ cli();
+ good_marker(3);
+ unlock_vbios(map);
+ good_marker(4);
+ rv = set_mode(map, mode, x, y, bp, 0, 0);
+ if (rv)
+ bad_marker(5);
+ else
+ good_marker(5);
+ relock_vbios(map);
+ good_marker(6);
+ sti();
+
+ debug("Patch mode %02x to resolution %dx%d complete\r\n", mode, x, y);
+ }
+ close_vbios(map);
+
+ return rv;
+}
diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c
index 0221fcf7..0a436f4c 100644
--- a/com32/lib/sys/vesa/initvesa.c
+++ b/com32/lib/sys/vesa/initvesa.c
@@ -37,6 +37,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/fpu.h>
+#include <syslinux/video.h>
#include "vesa.h"
#include "video.h"
#include "fill.h"
@@ -240,12 +241,10 @@ static int vesacon_set_mode(int x, int y)
__vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf];
/* Download the SYSLINUX- or BIOS-provided font */
- rm.eax.w[0] = 0x0018; /* Query custom font */
- __intcall(0x22, &rm, &rm);
- if (!(rm.eflags.l & EFLAGS_CF) && rm.eax.b[0]) {
- __vesacon_font_height = rm.eax.b[0];
- rom_font = MK_PTR(rm.es, rm.ebx.w[0]);
- } else {
+ __vesacon_font_height = syslinux_font_query(&rom_font);
+ if (!__vesacon_font_height) {
+ /* Get BIOS 8x16 font */
+
rm.eax.w[0] = 0x1130; /* Get Font Information */
rm.ebx.w[0] = 0x0600; /* Get 8x16 ROM font */
__intcall(0x10, &rm, &rm);
@@ -270,17 +269,13 @@ static int vesacon_set_mode(int x, int y)
__vesacon_init_copy_to_screen();
/* Tell syslinux we changed video mode */
- rm.eax.w[0] = 0x0017; /* Report video mode change */
/* In theory this should be:
- rm.ebx.w[0] = (mi->mode_attr & 4) ? 0x0007 : 0x000f;
+ flags = (mi->mode_attr & 4) ? 0x0007 : 0x000f;
However, that would assume all systems that claim to handle text
output in VESA modes actually do that... */
- rm.ebx.w[0] = 0x000f;
- rm.ecx.w[0] = mi->h_res;
- rm.edx.w[0] = mi->v_res;
- __intcall(0x22, &rm, NULL);
+ syslinux_report_video_mode(0x000f, mi->h_res, mi->v_res);
__vesacon_pixel_format = bestpxf;
@@ -323,8 +318,13 @@ int __vesacon_init(int x, int y)
return 10;
rv = vesacon_set_mode(x, y);
- if (rv)
- return rv;
+ if (rv) {
+ /* Try to see if we can just patch the BIOS... */
+ if (__vesacon_i915resolution(x, y))
+ return rv;
+ if (vesacon_set_mode(x, y))
+ return rv;
+ }
init_text_display();
diff --git a/com32/lib/sys/vesa/screencpy.c b/com32/lib/sys/vesa/screencpy.c
index b66e8854..9740ea14 100644
--- a/com32/lib/sys/vesa/screencpy.c
+++ b/com32/lib/sys/vesa/screencpy.c
@@ -43,7 +43,7 @@ static struct win_info {
static inline int __constfunc ilog2(unsigned int x)
{
-asm("bsrl %1,%0": "=r"(x):"rm"(x));
+ asm("bsrl %1,%0" : "=r"(x) : "rm"(x));
return x;
}
diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h
index 764228a0..d14494b1 100644
--- a/com32/lib/sys/vesa/video.h
+++ b/com32/lib/sys/vesa/video.h
@@ -92,4 +92,6 @@ void __vesacon_set_cursor(int, int, bool);
void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t);
void __vesacon_init_copy_to_screen(void);
+int __vesacon_i915resolution(int x, int y);
+
#endif /* LIB_SYS_VESA_VIDEO_H */
diff --git a/com32/lib/sys/vesaserial_write.c b/com32/lib/sys/vesaserial_write.c
index 47527c3a..775ca19e 100644
--- a/com32/lib/sys/vesaserial_write.c
+++ b/com32/lib/sys/vesaserial_write.c
@@ -38,7 +38,7 @@
#include <console.h>
#include "file.h"
-extern int __vesacon_open(void);
+extern int __vesacon_open(struct file_info *);
extern int __vesacon_close(struct file_info *);
extern ssize_t __vesacon_write(struct file_info *, const void *, size_t);
extern ssize_t __xserial_write(struct file_info *, const void *, size_t);
diff --git a/com32/lib/syslinux/getadv.c b/com32/lib/syslinux/getadv.c
index 456084b0..5578313e 100644
--- a/com32/lib/syslinux/getadv.c
+++ b/com32/lib/syslinux/getadv.c
@@ -39,7 +39,7 @@
const void *syslinux_getadv(int tag, size_t * size)
{
const uint8_t *p;
- size_t left, len;
+ size_t left;
p = syslinux_adv_ptr();
left = syslinux_adv_size();
diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index db985163..df793625 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -253,6 +253,9 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
case 'n': /* "normal" */
video_mode = 0xffff;
break;
+ case 'c': /* "current" */
+ video_mode = 0x0f04;
+ break;
default:
video_mode = strtoul(arg, NULL, 0);
break;
diff --git a/com32/lib/syslinux/pxe_dns.c b/com32/lib/syslinux/pxe_dns.c
new file mode 100644
index 00000000..9ab95137
--- /dev/null
+++ b/com32/lib/syslinux/pxe_dns.c
@@ -0,0 +1,70 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxe_dns.c
+ *
+ * Resolve a hostname via DNS
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <com32.h>
+
+#include <syslinux/pxe.h>
+
+/* Returns the status code from PXE (0 on success),
+ or -1 on invocation failure */
+uint32_t pxe_dns(const char *hostname)
+{
+ com32sys_t regs;
+ union {
+ unsigned char b[4];
+ uint32_t ip;
+ } q;
+
+ /* Is this a dot-quad? */
+ if (sscanf(hostname, "%hhu.%hhu.%hhu.%hhu",
+ &q.b[0], &q.b[1], &q.b[2], &q.b[3]) == 4)
+ return q.ip;
+
+ memset(&regs, 0, sizeof regs);
+ regs.eax.w[0] = 0x0010;
+ regs.es = SEG(__com32.cs_bounce);
+ regs.ebx.w[0] = OFFS(__com32.cs_bounce);
+
+ strcpy((char *)__com32.cs_bounce, hostname);
+
+ __intcall(0x22, &regs, &regs);
+
+ if (regs.eflags.l & EFLAGS_CF)
+ return 0;
+
+ return regs.eax.l;
+}
diff --git a/com32/lib/syslinux/video/fontquery.c b/com32/lib/syslinux/video/fontquery.c
new file mode 100644
index 00000000..dd5d86e3
--- /dev/null
+++ b/com32/lib/syslinux/video/fontquery.c
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/forcetext.c
+ */
+
+#include <syslinux/video.h>
+#include <com32.h>
+
+/*
+ * Returns height of font or zero if no custom font loaded
+ */
+int syslinux_font_query(uint8_t **font)
+{
+ static com32sys_t ireg;
+ com32sys_t oreg;
+ int height;
+
+ ireg.eax.w[0] = 0x0018;
+ __intcall(0x22, &ireg, &oreg);
+
+ height = !(oreg.eflags.l & EFLAGS_CF) ? oreg.eax.b[0] : 0;
+ if (height)
+ *font = MK_PTR(oreg.es, oreg.ebx.w[0]);
+
+ return height;
+}
+
diff --git a/com32/lib/syslinux/video/forcetext.c b/com32/lib/syslinux/video/forcetext.c
new file mode 100644
index 00000000..136cb279
--- /dev/null
+++ b/com32/lib/syslinux/video/forcetext.c
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/forcetext.c
+ */
+
+#include <syslinux/video.h>
+#include <com32.h>
+
+void syslinux_force_text_mode(void)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.w[0] = 0x0005;
+ __intcall(0x22, &ireg, NULL);
+}
diff --git a/com32/lib/syslinux/video/reportmode.c b/com32/lib/syslinux/video/reportmode.c
new file mode 100644
index 00000000..57fd6fdc
--- /dev/null
+++ b/com32/lib/syslinux/video/reportmode.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/reportmode.c
+ */
+
+#include <syslinux/video.h>
+#include <com32.h>
+
+void syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.w[0] = 0x0017;
+ ireg.ebx.w[0] = flags;
+ ireg.ecx.w[0] = xsize;
+ ireg.edx.w[0] = ysize;
+ __intcall(0x22, &ireg, NULL);
+}
diff --git a/com32/lib/zlib/crc32.c b/com32/lib/zlib/crc32.c
index 447f138e..67e6f31e 100644
--- a/com32/lib/zlib/crc32.c
+++ b/com32/lib/zlib/crc32.c
@@ -100,7 +100,7 @@ local void make_crc_table()
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+ for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
poly |= 1UL << (31 - p[n]);
/* generate a crc for every 8-bit value */
diff --git a/com32/mboot/Makefile b/com32/mboot/Makefile
index c1ac76fb..7e6c2e96 100644
--- a/com32/mboot/Makefile
+++ b/com32/mboot/Makefile
@@ -24,7 +24,7 @@ LNXLIBS = ../libutil/libutil_lnx.a
MODULES = mboot.c32
TESTFILES =
-OBJS = mboot.o map.o mem.o initvesa.o apm.o solaris.o
+OBJS = mboot.o map.o mem.o initvesa.o apm.o solaris.o syslinux.o
all: $(MODULES) $(TESTFILES)
diff --git a/com32/mboot/map.c b/com32/mboot/map.c
index a32f9b3b..267e50c8 100644
--- a/com32/mboot/map.c
+++ b/com32/mboot/map.c
@@ -151,6 +151,10 @@ struct multiboot_header *map_image(void *ptr, size_t len)
!eh->e_phnum || eh->e_phoff + eh->e_phentsize * eh->e_phnum > len)
eh = NULL; /* No valid ELF header found */
+ /* Is this a Solaris kernel? */
+ if (!set.solaris && eh && kernel_is_solaris(eh))
+ opt.solaris = true;
+
/*
* Note: the Multiboot Specification implies that AOUT_KLUDGE should
* have precedence over the ELF header. However, Grub disagrees, and
diff --git a/com32/mboot/mboot.c b/com32/mboot/mboot.c
index 8425e068..915c7857 100644
--- a/com32/mboot/mboot.c
+++ b/com32/mboot/mboot.c
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -36,7 +36,7 @@
struct multiboot_info mbinfo;
struct syslinux_pm_regs regs;
-struct my_options opt;
+struct my_options opt, set;
struct module_data {
void *data;
@@ -161,11 +161,21 @@ int main(int argc, char *argv[])
argv++;
while (*argv) {
- if (!strcmp(*argv, "-solaris"))
- opt.solaris = true;
- else if (!strcmp(*argv, "-aout"))
- opt.aout = true;
- else
+ bool v = true;
+ const char *p = *argv;
+
+ if (!memcmp(p, "-no", 3)) {
+ v = false;
+ p += 3;
+ }
+
+ if (!strcmp(p, "-solaris")) {
+ opt.solaris = v;
+ set.solaris = true;
+ } else if (!strcmp(p, "-aout")) {
+ opt.aout = v;
+ set.aout = true;
+ } else
break;
argv++;
}
@@ -222,6 +232,8 @@ int main(int argc, char *argv[])
/* Add auxilliary information */
mboot_make_memmap();
mboot_apm();
+ mboot_syslinux_info();
+
if (opt.solaris)
mboot_solaris_dhcp_hack();
diff --git a/com32/mboot/mboot.h b/com32/mboot/mboot.h
index 993b31a8..b646cd36 100644
--- a/com32/mboot/mboot.h
+++ b/com32/mboot/mboot.h
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -50,6 +50,7 @@
#include <syslinux/loadfile.h>
#include <syslinux/movebits.h>
#include <syslinux/bootpm.h>
+#include <syslinux/config.h>
#include "mb_header.h"
#include "mb_info.h"
@@ -72,7 +73,7 @@ extern struct syslinux_pm_regs regs;
extern struct my_options {
bool solaris;
bool aout;
-} opt;
+} opt, set;
/* map.c */
#define MAP_HIGH 1
@@ -90,8 +91,12 @@ void mboot_make_memmap(void);
void mboot_apm(void);
/* solaris.c */
+bool kernel_is_solaris(const Elf32_Ehdr *);
void mboot_solaris_dhcp_hack(void);
+/* syslinux.c */
+void mboot_syslinux_info(void);
+
/* initvesa.c */
void set_graphics_mode(const struct multiboot_header *mbh,
struct multiboot_info *mbi);
diff --git a/com32/mboot/solaris.c b/com32/mboot/solaris.c
index 3b316606..1b153ddb 100644
--- a/com32/mboot/solaris.c
+++ b/com32/mboot/solaris.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -35,12 +35,21 @@
#include "mboot.h"
#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+
+bool kernel_is_solaris(const Elf32_Ehdr *eh)
+{
+ return eh->e_ident[EI_OSABI] == 6; /* ABI == Solaris */
+}
void mboot_solaris_dhcp_hack(void)
{
void *dhcpdata;
size_t dhcplen;
+ if (syslinux_derivative_info()->c.filesystem != SYSLINUX_FS_PXELINUX)
+ return;
+
if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
mbinfo.drives_addr = map_data(dhcpdata, dhcplen, 4, 0);
if (mbinfo.drives_addr) {
diff --git a/com32/mboot/syslinux.c b/com32/mboot/syslinux.c
new file mode 100644
index 00000000..7de3853e
--- /dev/null
+++ b/com32/mboot/syslinux.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux.c
+ *
+ * Syslinux-specific information for the kernel
+ */
+
+#include <syslinux/config.h>
+#include "mboot.h"
+
+void mboot_syslinux_info(void)
+{
+ const struct syslinux_version *sv;
+
+ sv = syslinux_version();
+ mbinfo.boot_loader_name = map_string(sv->version_string);
+ if (mbinfo.boot_loader_name)
+ mbinfo.flags |= MB_INFO_BOOT_LOADER_NAME;
+}
diff --git a/com32/menu/menu.h b/com32/menu/menu.h
index 52b4e4dc..1e596e1d 100644
--- a/com32/menu/menu.h
+++ b/com32/menu/menu.h
@@ -180,6 +180,7 @@ extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
/* These are global parameters regardless of which menu we're displaying */
extern int shiftkey;
extern int hiddenmenu;
+extern int clearmenu;
extern long long totaltimeout;
void parse_configs(char **argv);
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index cbeb9a18..0c392646 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* 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
@@ -616,8 +616,9 @@ static inline int shift_is_held(void)
static void print_timeout_message(int tol, int row, const char *msg)
{
+ static int last_msg_len = 0;
char buf[256];
- int nc = 0, nnc;
+ int nc = 0, nnc, padc;
const char *tp = msg;
char tc;
char *tq = buf;
@@ -686,9 +687,17 @@ static void print_timeout_message(int tol, int row, const char *msg)
}
*tq = '\0';
- /* Let's hope 4 spaces on each side is enough... */
- printf("\033[%d;%dH\2#14 %s ", row,
- HSHIFT + 1 + ((WIDTH - nc - 8) >> 1), buf);
+ if (nc >= last_msg_len) {
+ padc = 0;
+ } else {
+ padc = (last_msg_len - nc + 1) >> 1;
+ }
+
+ printf("\033[%d;%dH\2#14%*s%s%*s", row,
+ HSHIFT + 1 + ((WIDTH - nc) >> 1) - padc,
+ padc, "", buf, padc, "");
+
+ last_msg_len = nc;
}
/* Set the background screen, etc. */
@@ -724,6 +733,9 @@ static const char *do_hidden_menu(void)
}
}
+ /* Clear the message from the screen */
+ print_timeout_message(0, HIDDEN_ROW, "");
+
if (cm->ontimeout)
return cm->ontimeout;
else
@@ -1118,6 +1130,9 @@ int main(int argc, char *argv[])
local_cursor_enable(true);
cmdline = run_menu();
+ if (clearmenu)
+ clear_screen();
+
local_cursor_enable(false);
printf("\033[?25h\033[%d;1H\033[0m", END_ROW);
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index a248721e..d4c8848c 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* 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
@@ -34,6 +34,7 @@ struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
/* These are global parameters regardless of which menu we're displaying */
int shiftkey = 0; /* Only display menu if shift key pressed */
int hiddenmenu = 0;
+int clearmenu = 0;
long long totaltimeout = 0;
/* Keep track of global default */
@@ -690,6 +691,8 @@ static void parse_config_file(FILE * f)
m->menu_background = refdup_word(&p);
} else if ((ep = looking_at(p, "hidden"))) {
hiddenmenu = 1;
+ } else if ((ep = looking_at(p, "clear"))) {
+ clearmenu = 1;
} else if ((ep = is_message_name(p, &msgnr))) {
refstr_put(m->messages[msgnr]);
m->messages[msgnr] = refstrdup(skipspace(ep));
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 35906587..44bc1dfb 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -21,7 +21,8 @@ include ../MCONFIG
MODULES = chain.c32 config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
disk.c32 pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 \
meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \
- kbdmap.c32 cmd.c32 vpdtest.c32 gpxecmd.c32 ifcpu.c32
+ kbdmap.c32 cmd.c32 vpdtest.c32 gpxecmd.c32 ifcpu.c32 \
+ cpuid.c32
TESTFILES =
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 27220143..ad746ee7 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* 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
@@ -46,14 +46,22 @@
* when you want more than one ISOLINUX per CD/DVD.
*
* ntldr=<loader>:
- * equivalent to -seg 0x2000 -file <loader>, used with WinNT's loaders
+ * equivalent to seg=0x2000 file=<loader> sethidden,
+ * used with WinNT's loaders
+ *
+ * cmldr=<loader>:
+ * used with Recovery Console of Windows NT/2K/XP.
+ * same as ntldr=<loader> & "cmdcons\0" written to
+ * the system name field in the bootsector
*
* freedos=<loader>:
- * equivalent to -seg 0x60 -file <loader>, used with FreeDOS kernel.sys.
+ * equivalent to seg=0x60 file=<loader> sethidden,
+ * used with FreeDOS kernel.sys.
*
* msdos=<loader>
* pcdos=<loader>
- * equivalent to -seg 0x70 -file <loader>, used with DOS' io.sys.
+ * equivalent to seg=0x70 file=<loader> sethidden,
+ * used with DOS' io.sys.
*
* swap:
* if the disk is not fd0/hd0, install a BIOS stub which swaps
@@ -63,6 +71,10 @@
* change type of primary partitions with IDs 01, 04, 06, 07,
* 0b, 0c, or 0e to 1x, except for the selected partition, which
* is converted the other way.
+ *
+ * sethidden:
+ * update the "hidden sectors" (partition offset) field in a
+ * FAT/NTFS boot sector.
*/
#include <com32.h>
@@ -76,6 +88,7 @@
#include <syslinux/loadfile.h>
#include <syslinux/bootrm.h>
#include <syslinux/config.h>
+#include <syslinux/video.h>
#define SECTOR 512 /* bytes/sector */
@@ -84,10 +97,18 @@ static struct options {
uint16_t keeppxe;
uint16_t seg;
bool isolinux;
+ bool cmldr;
bool swap;
bool hide;
+ bool sethidden;
} opt;
+struct data_area {
+ void *data;
+ addr_t base;
+ addr_t size;
+};
+
static inline void error(const char *msg)
{
fputs(msg, stderr);
@@ -388,10 +409,13 @@ static struct part_entry *find_logical_partition(int whichpart, char *table,
/* Adjust the offset to account for the extended partition itself */
ptab[i].start_lba += self->start_lba;
- /* Sanity check entry: must not extend outside the extended partition.
- This is necessary since some OSes put crap in some entries. */
- if (ptab[i].start_lba + ptab[i].length <= self->start_lba ||
- ptab[i].start_lba >= self->start_lba + self->length)
+ /*
+ * Sanity check entry: must not extend outside the
+ * extended partition. This is necessary since some OSes
+ * put crap in some entries. Note that root is non-NULL here.
+ */
+ if (ptab[i].start_lba + ptab[i].length <= root->start_lba ||
+ ptab[i].start_lba >= root->start_lba + root->length)
continue;
/* OK, it's a data partition. Is it the one we're looking for? */
@@ -437,7 +461,7 @@ static struct part_entry *find_logical_partition(int whichpart, char *table,
return NULL;
}
-static void do_boot(void *boot_sector, size_t boot_size,
+static void do_boot(struct data_area *data, int ndata,
struct syslinux_rm_regs *regs)
{
uint16_t *const bios_fbm = (uint16_t *) 0x413;
@@ -448,7 +472,6 @@ static void do_boot(void *boot_sector, size_t boot_size,
uint8_t driveno = regs->edx.b[0];
uint8_t swapdrive = driveno & 0x80;
int i;
- addr_t loadbase = opt.seg ? (opt.seg << 4) : 0x7c00;
mmap = syslinux_memory_map();
@@ -457,16 +480,19 @@ static void do_boot(void *boot_sector, size_t boot_size,
return;
}
- /* Nothing below 0x7c00, much simpler... */
-
- if (boot_size >= dosmem - loadbase)
+ endimage = 0;
+ for (i = 0; i < ndata; i++) {
+ if (data[i].base + data[i].size > endimage)
+ endimage = data[i].base + data[i].size;
+ }
+ if (endimage > dosmem)
goto too_big;
- endimage = loadbase + boot_size;
-
- if (syslinux_add_movelist
- (&mlist, loadbase, (addr_t) boot_sector, boot_size))
- goto enomem;
+ for (i = 0; i < ndata; i++) {
+ if (syslinux_add_movelist(&mlist, data[i].base,
+ (addr_t)data[i].data, data[i].size))
+ goto enomem;
+ }
if (opt.swap && driveno != swapdrive) {
static const uint8_t swapstub_master[] = {
@@ -548,6 +574,9 @@ static void do_boot(void *boot_sector, size_t boot_size,
/* Tell the shuffler not to muck with this area... */
syslinux_add_memmap(&mmap, endimage, 0xa0000 - endimage, SMT_RESERVED);
+ /* Force text mode */
+ syslinux_force_text_mode();
+
fputs("Booting...\n", stdout);
syslinux_shuffle_boot_rm(mlist, mmap, opt.keeppxe, regs);
error("Chainboot failed!\n");
@@ -637,10 +666,30 @@ static uint32_t get_file_lba(const char *filename)
return lba;
}
+static void usage(void)
+{
+ error("Usage: chain.c32 hd<disk#> [<partition>] [options]\n"
+ " chain.c32 fd<disk#> [options]\n"
+ " chain.c32 mbr:<id> [<partition>] [options]\n"
+ " chain.c32 boot [<partition>] [options]\n"
+ "Options: file=<loader> load file, instead of boot sector\n"
+ " isolinux=<loader> load another version of ISOLINUX\n"
+ " ntldr=<loader> load Windows NTLDR, SETUPLDR.BIN or BOOTMGR\n"
+ " cmldr=<loader> load Recovery Console of Windows NT/2K/XP\n"
+ " freedos=<loader> load FreeDOS kernel.sys\n"
+ " msdos=<loader> load MS-DOS io.sys\n"
+ " pcdos=<loader> load PC-DOS ibmbio.com\n"
+ " seg=<segment> jump to <seg>:0000 instead of 0000:7C00\n"
+ " swap swap drive numbers, if bootdisk is not fd0/hd0\n"
+ " hide hide primary partitions, except selected partition\n"
+ " sethidden set the FAT/NTFS hidden sectors field\n"
+ );
+}
+
+
int main(int argc, char *argv[])
{
char *mbr, *p;
- void *boot_sector = NULL;
struct part_entry *partinfo;
struct syslinux_rm_regs regs;
char *drivename, *partition;
@@ -649,7 +698,10 @@ int main(int argc, char *argv[])
uint32_t file_lba = 0;
unsigned char *isolinux_bin;
uint32_t *checksum, *chkhead, *chktail;
- size_t boot_size = SECTOR;
+ struct data_area data[3];
+ int ndata = 0;
+ addr_t load_base;
+ static const char cmldr_signature[8] = "cmdcons";
openconsole(&dev_null_r, &dev_stdcon_w);
@@ -675,24 +727,41 @@ int main(int argc, char *argv[])
} else if (!strncmp(argv[i], "ntldr=", 6)) {
opt.seg = 0x2000; /* NTLDR wants this address */
opt.loadfile = argv[i] + 6;
+ opt.sethidden = true;
+ } else if (!strncmp(argv[i], "cmldr=", 6)) {
+ opt.seg = 0x2000; /* CMLDR wants this address */
+ opt.loadfile = argv[i] + 6;
+ opt.cmldr = true;
+ opt.sethidden = true;
} else if (!strncmp(argv[i], "freedos=", 8)) {
opt.seg = 0x60; /* FREEDOS wants this address */
opt.loadfile = argv[i] + 8;
+ opt.sethidden = true;
} else if (!strncmp(argv[i], "msdos=", 6) ||
!strncmp(argv[i], "pcdos=", 6)) {
opt.seg = 0x70; /* MS-DOS 2.0+ wants this address */
opt.loadfile = argv[i] + 6;
+ opt.sethidden = true;
} else if (!strcmp(argv[i], "swap")) {
opt.swap = true;
+ } else if (!strcmp(argv[i], "noswap")) {
+ opt.swap = false;
} else if (!strcmp(argv[i], "hide")) {
opt.hide = true;
+ } else if (!strcmp(argv[i], "nohide")) {
+ opt.hide = false;
} else if (!strcmp(argv[i], "keeppxe")) {
opt.keeppxe = 3;
- } else
- if (((argv[i][0] == 'h' || argv[i][0] == 'f') && argv[i][1] == 'd')
- || !strncmp(argv[i], "mbr:", 4)
- || !strncmp(argv[i], "mbr=", 4)
- || !strcmp(argv[i], "boot") || !strncmp(argv[i], "boot,", 5)) {
+ } else if (!strcmp(argv[i], "sethidden")) {
+ opt.sethidden = true;
+ } else if (!strcmp(argv[i], "nosethidden")) {
+ opt.sethidden = false;
+ } else if (((argv[i][0] == 'h' || argv[i][0] == 'f')
+ && argv[i][1] == 'd')
+ || !strncmp(argv[i], "mbr:", 4)
+ || !strncmp(argv[i], "mbr=", 4)
+ || !strcmp(argv[i], "boot")
+ || !strncmp(argv[i], "boot,", 5)) {
drivename = argv[i];
p = strchr(drivename, ',');
if (p) {
@@ -703,20 +772,7 @@ int main(int argc, char *argv[])
partition = argv[++i];
}
} else {
- error
- ("Usage: chain.c32 hd<disk#> [<partition>] [options]\n"
- " chain.c32 fd<disk#> [options]\n"
- " chain.c32 mbr:<id> [<partition>] [options]\n"
- " chain.c32 boot [<partition>] [options]\n"
- "Options: file=<loader> load file, instead of boot sector\n"
- " isolinux=<loader> load another version of ISOLINUX\n"
- " ntldr=<loader> load Windows bootloaders: NTLDR, SETUPLDR, BOOTMGR\n"
- " freedos=<loader> load FreeDOS kernel.sys\n"
- " msdos=<loader> load MS-DOS io.sys\n"
- " pcdos=<loader> load PC-DOS ibmbio.com\n"
- " seg=<segment> jump to <seg>:0000 instead of 0000:7C00\n"
- " swap swap drive numbers, if bootdisk is not fd0/hd0\n"
- " hide hide primary partitions, except selected partition\n");
+ usage();
goto bail;
}
}
@@ -755,7 +811,6 @@ int main(int argc, char *argv[])
regs.ebx.b[0] = regs.edx.b[0] = drive;
whichpart = 0; /* Default */
-
if (partition)
whichpart = strtoul(partition, NULL, 0);
@@ -763,6 +818,14 @@ int main(int argc, char *argv[])
error("Warning: Partitions of floppy devices may not work\n");
}
+ /*
+ * grldr of Grub4dos wants the partition number in DH:
+ * -1: whole drive (default)
+ * 0-3: primary partitions
+ * 4-*: logical partitions
+ */
+ regs.edx.b[1] = whichpart-1;
+
/* Get the disk geometry and disk access setup */
if (get_disk_params(drive)) {
error("Cannot get disk parameters\n");
@@ -786,7 +849,6 @@ int main(int argc, char *argv[])
/* Boot the MBR */
partinfo = NULL;
- boot_sector = mbr;
} else if (whichpart <= 4) {
/* Boot a primary partition */
@@ -808,12 +870,16 @@ int main(int argc, char *argv[])
}
/* Do the actual chainloading */
+ load_base = opt.seg ? (opt.seg << 4) : 0x7c00;
+
if (opt.loadfile) {
fputs("Loading the boot file...\n", stdout);
- if (loadfile(opt.loadfile, &boot_sector, &boot_size)) {
+ if (loadfile(opt.loadfile, &data[ndata].data, &data[ndata].size)) {
error("Failed to load the boot file\n");
goto bail;
}
+ data[ndata].base = load_base;
+ load_base = 0x7c00; /* If we also load a boot sector */
/* Create boot info table: needed when you want to chainload
another version of ISOLINUX (or another bootlaoder that needs
@@ -840,7 +906,7 @@ int main(int argc, char *argv[])
LBA of primary volume descriptor should already be set to 16.
*/
- isolinux_bin = (unsigned char *)boot_sector;
+ isolinux_bin = (unsigned char *)data[ndata].data;
/* Get LBA address of bootfile */
file_lba = get_file_lba(opt.loadfile);
@@ -850,20 +916,27 @@ int main(int argc, char *argv[])
goto bail;
}
/* Set it */
- *((uint32_t *) & isolinux_bin[12]) = file_lba;
+ *((uint32_t *) &isolinux_bin[12]) = file_lba;
/* Set boot file length */
- *((uint32_t *) & isolinux_bin[16]) = boot_size;
+ *((uint32_t *) &isolinux_bin[16]) = data[ndata].size;
/* Calculate checksum */
- checksum = (uint32_t *) & isolinux_bin[20];
- chkhead = (uint32_t *) & isolinux_bin[64];
- chktail = (uint32_t *) & isolinux_bin[boot_size - 1];
- /* Fresh checksum and clear possibly fractional uint32_t at the end */
- *checksum = *((uint32_t *) & isolinux_bin[boot_size]) = 0;
-
- while (chkhead <= chktail) {
+ checksum = (uint32_t *) &isolinux_bin[20];
+ chkhead = (uint32_t *) &isolinux_bin[64];
+ chktail = (uint32_t *) &isolinux_bin[data[ndata].size & ~3];
+ *checksum = 0;
+ while (chkhead < chktail)
*checksum += *chkhead++;
+
+ /*
+ * Deal with possible fractional dword at the end;
+ * this *should* never happen...
+ */
+ if (data[ndata].size & 3) {
+ uint32_t xword = 0;
+ memcpy(&xword, chkhead, data[ndata].size & 3);
+ *checksum += xword;
}
} else {
error
@@ -872,30 +945,60 @@ int main(int argc, char *argv[])
}
}
- } else if (partinfo) {
+ ndata++;
+ }
+
+ if (!opt.loadfile || data[0].base >= 0x7c00 + SECTOR) {
/* Actually read the boot sector */
- /* Pick the first buffer that isn't already in use */
- if (!(boot_sector = read_sector(partinfo->start_lba))) {
+ if (!partinfo) {
+ data[ndata].data = mbr;
+ } else if (!(data[ndata].data = read_sector(partinfo->start_lba))) {
error("Cannot read boot sector\n");
goto bail;
}
- }
-
- if (!opt.loadfile) {
- if (*(uint16_t *) ((char *)boot_sector + boot_size - 2) != 0xaa55) {
- error
- ("Boot sector signature not found (unbootable disk/partition?)\n");
+ data[ndata].size = SECTOR;
+ data[ndata].base = load_base;
+
+ if (!opt.loadfile &&
+ *(uint16_t *)((char *)data[ndata].data +
+ data[ndata].size - 2) != 0xaa55) {
+ error("Boot sector signature not found (unbootable disk/partition?)\n");
goto bail;
}
+
+ /*
+ * To boot the Recovery Console of Windows NT/2K/XP we need to write
+ * the string "cmdcons\0" to memory location 0000:7C03.
+ * Memory location 0000:7C00 contains the bootsector of the partition.
+ */
+ if (partinfo && opt.cmldr) {
+ memcpy((char *)data[ndata].data+3, cmldr_signature,
+ sizeof cmldr_signature);
+ }
+
+ /*
+ * Modify the hidden sectors (partition offset) copy in memory;
+ * this modifies the field used by FAT and NTFS filesystems, and
+ * possibly other boot loaders which use the same format.
+ */
+ if (partinfo && opt.sethidden) {
+ *(uint32_t *)((char *)data[ndata].data + 28) =
+ partinfo->start_lba;
+ }
+
+ ndata++;
}
if (partinfo) {
/* 0x7BE is the canonical place for the first partition entry. */
+ data[ndata].data = partinfo;
+ data[ndata].base = 0x7be;
+ data[ndata].size = sizeof *partinfo;
+ ndata++;
regs.esi.w[0] = 0x7be;
- memcpy((char *)0x7be, partinfo, sizeof(*partinfo));
}
- do_boot(boot_sector, boot_size, &regs);
+ do_boot(data, ndata, &regs);
bail:
return 255;
diff --git a/com32/modules/cpuid.c b/com32/modules/cpuid.c
new file mode 100644
index 00000000..62a756e5
--- /dev/null
+++ b/com32/modules/cpuid.c
@@ -0,0 +1,60 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/cpu.h>
+#include <console.h>
+#include <com32.h>
+
+static void dump_reg(const char *name, uint32_t val)
+{
+ int i;
+
+ printf("%-3s : %10d 0x%08x ", name, val, val);
+
+ for (i = 3; i >= 0; i--) {
+ uint8_t c = val >> (i*8);
+ putchar((c >= ' ' && c <= '~') ? c : '.');
+ }
+ putchar('\n');
+}
+
+int main(int argc, char *argv[])
+{
+ uint32_t leaf, counter;
+ uint32_t eax, ebx, ecx, edx;
+
+ openconsole(&dev_null_r, &dev_stdcon_w);
+
+ if (argc < 2 || argc > 4) {
+ printf("Usage: %s leaf [counter]\n", argv[0]);
+ exit(1);
+ }
+
+ leaf = strtoul(argv[1], NULL, 0);
+ counter = (argv > 2) ? strtoul(argv[2], NULL, 0) : 0;
+
+ if (!cpu_has_eflag(EFLAGS_ID)) {
+ printf("The CPUID instruction is not supported\n");
+ exit(1);
+ }
+
+ cpuid_count(leaf, counter, &eax, &ebx, &ecx, &edx);
+
+ dump_reg("eax", eax);
+ dump_reg("ebx", ebx);
+ dump_reg("ecx", ecx);
+ dump_reg("edx", edx);
+
+ return 0;
+}
diff --git a/com32/rosh/MCONFIG b/com32/rosh/MCONFIG
index 30029d15..25c41396 100644
--- a/com32/rosh/MCONFIG
+++ b/com32/rosh/MCONFIG
@@ -17,11 +17,11 @@
## Include the COM32 common configurables
include ../MCONFIG
-# CFLAGS = $(GCCOPT) -W -Wall -march=i386 \
+# CFLAGS = $(GCCOPT) $(GCCWARN) -march=i386 \
# -fomit-frame-pointer -D__COM32__ \
# -nostdinc -iwithprefix include \
# -I$(com32)/libutil/include -I$(com32)/include
# -g3 -dD
-# LNXCFLAGS = -I$(com32)/libutil/include -W -Wall -O -g3 -D_GNU_SOURCE -dD
+# LNXCFLAGS = -I$(com32)/libutil/include $(GCCWARN) -O -g3 -D_GNU_SOURCE -dD
# -U__GNUC__
diff --git a/com32/rosh/rosh.c b/com32/rosh/rosh.c
index 9a4edae2..720d8644 100644
--- a/com32/rosh/rosh.c
+++ b/com32/rosh/rosh.c
@@ -37,7 +37,7 @@
#define APP_YEAR "2008"
#define APP_VER "beta-b032"
-void rosh_version()
+void rosh_version(void)
{
printf("%s v %s; (c) %s %s.\n", APP_LONGNAME, APP_VER, APP_YEAR,
APP_AUTHOR);
@@ -224,7 +224,7 @@ void rosh_print_tc(struct termios *tio)
* Switches console over to raw input mode. Allows get_key to get just
* 1 key sequence (without delay or display)
*/
-void rosh_console_raw()
+void rosh_console_raw(void)
{
// struct termios itio, ntio;
// tcgetattr(0, &itio);
@@ -241,7 +241,7 @@ void rosh_console_raw()
/*
* Switches back to standard getline mode.
*/
-void rosh_console_std()
+void rosh_console_std(void)
{
// struct termios itio, ntio;
console_ansi_std();
@@ -252,7 +252,7 @@ void rosh_console_std()
* Attempts to get a single key from the console
* returns key pressed
*/
-int rosh_getkey()
+int rosh_getkey(void)
{
int inc;
diff --git a/com32/sysdump/Makefile b/com32/sysdump/Makefile
new file mode 100644
index 00000000..bffee3a2
--- /dev/null
+++ b/com32/sysdump/Makefile
@@ -0,0 +1,60 @@
+## -----------------------------------------------------------------------
+##
+## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2010 Intel Corporation; author: H. Peter Anvin
+##
+## 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., 51 Franklin St, Fifth Floor,
+## Boston MA 02110-1301, USA; either version 2 of the License, or
+## (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Simple menu system
+##
+
+topdir = ../..
+include ../MCONFIG
+-include $(topdir)/version.mk
+
+LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC)
+LNXLIBS = ../libutil/libutil_lnx.a
+
+MODULES = sysdump.c32
+TESTFILES =
+
+SRCS = $(wildcard *.c)
+OBJS = $(patsubst %.c,%.o,$(SRCS))
+
+# The DATE is set on the make command line when building binaries for
+# official release. Otherwise, substitute a hex string that is pretty much
+# guaranteed to be unique to be unique from build to build.
+ifndef HEXDATE
+HEXDATE := $(shell $(PERL) $(topdir)/now.pl $(SRCS) $(wildcard *.h))
+endif
+ifndef DATE
+DATE := $(shell sh $(topdir)/gen-id.sh $(VERSION) $(HEXDATE))
+endif
+
+CFLAGS += -DDATE='"$(DATE)"'
+
+all: $(MODULES) $(TESTFILES)
+
+sysdump.elf : $(OBJS) $(LIBS) $(C_LIBS)
+ $(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist:
+ rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+ rm -f *.lnx
+
+spotless: clean
+ rm -f *.lss *.c32 *.com
+ rm -f *~ \#*
+
+install:
+
+-include .*.d
diff --git a/com32/sysdump/README b/com32/sysdump/README
new file mode 100644
index 00000000..2b825775
--- /dev/null
+++ b/com32/sysdump/README
@@ -0,0 +1,19 @@
+This is a very simple COMBOOT program which can be used to dump memory
+regions over a serial port. To use it, type on the SYSLINUX command
+line:
+
+memdump <port> <prefix> <start>,<len> <start>,<len>...
+
+For example:
+
+memdump 0 funnysystem- 0,0x600 0x9fc00,0x400 0xf0000,0x10000
+
+... dumps three memory ranges (the standard BIOS memory ranges, often
+useful) onto serial port 0. The <port> can either be in the range 0-3
+for the standard BIOS serial port, or the I/O address of the UART.
+
+The data is transferred using the YMODEM protocol; the Unix
+implementation of this protocol is called "rb" and is part of the
+"lrzsz" (or "rzsz") package. If one uses a terminal program like
+Minicom, there is often a way to invoke it from inside the terminal
+program; in Minicom, this is done with the Ctrl-A R control sequence.
diff --git a/com32/sysdump/backend.h b/com32/sysdump/backend.h
new file mode 100644
index 00000000..0926c8d5
--- /dev/null
+++ b/com32/sysdump/backend.h
@@ -0,0 +1,54 @@
+#ifndef BACKEND_H
+#define BACKEND_H
+
+#include <stddef.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "serial.h"
+
+/* Backend flags */
+#define BE_NEEDLEN 0x01
+
+struct backend {
+ const char *name;
+ const char *helpmsg;
+ int minargs;
+
+ size_t dbytes;
+ size_t zbytes;
+ const char **argv;
+
+ uint32_t now;
+
+ int (*write)(struct backend *);
+
+ z_stream zstream;
+ char *outbuf;
+ size_t alloc;
+};
+
+/* zout.c */
+int init_data(struct backend *be, const char *argv[]);
+int write_data(struct backend *be, const void *buf, size_t len);
+int flush_data(struct backend *be);
+
+/* cpio.c */
+#define cpio_init init_data
+int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
+ const char *filename);
+int cpio_mkdir(struct backend *be, const char *filename);
+int cpio_writefile(struct backend *be, const char *filename,
+ const void *data, size_t len);
+int cpio_close(struct backend *be);
+#define MODE_FILE 0100644
+#define MODE_DIR 0040755
+
+/* backends.c */
+struct backend *get_backend(const char *name);
+
+/* backends */
+extern struct backend be_tftp;
+extern struct backend be_ymodem;
+
+#endif /* BACKEND_H */
diff --git a/com32/sysdump/be_tftp.c b/com32/sysdump/be_tftp.c
new file mode 100644
index 00000000..07fdb084
--- /dev/null
+++ b/com32/sysdump/be_tftp.c
@@ -0,0 +1,143 @@
+/*
+ * TFTP data output backend
+ */
+
+#include <string.h>
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+#include <netinet/in.h>
+#include <sys/times.h>
+
+#include "backend.h"
+
+enum tftp_opcode {
+ TFTP_RRQ = 1,
+ TFTP_WRQ = 2,
+ TFTP_DATA = 3,
+ TFTP_ACK = 4,
+ TFTP_ERROR = 5,
+};
+
+struct tftp_state {
+ uint32_t my_ip;
+ uint32_t srv_ip;
+ uint16_t my_port;
+ uint16_t srv_port;
+ uint16_t seq;
+};
+
+static int send_ack_packet(struct tftp_state *tftp,
+ const void *pkt, size_t len)
+{
+ com32sys_t ireg, oreg;
+ t_PXENV_UDP_WRITE *uw = __com32.cs_bounce;
+ t_PXENV_UDP_READ *ur = __com32.cs_bounce;
+ clock_t start;
+ static const clock_t timeouts[] = {
+ 2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 15, 18, 21, 26, 31,
+ 37, 44, 53, 64, 77, 92, 110, 132, 159, 191, 229, 0
+ };
+ const clock_t *timeout;
+
+ memset(&ireg, 0, sizeof ireg);
+ ireg.eax.w[0] = 0x0009;
+
+ for (timeout = timeouts ; *timeout ; timeout++) {
+ memset(uw, 0, sizeof uw);
+ memcpy(uw+1, pkt, len);
+ uw->ip = tftp->srv_ip;
+ uw->src_port = tftp->my_port;
+ uw->dst_port = tftp->srv_port ? tftp->srv_port : htons(69);
+ uw->buffer_size = len;
+ uw->buffer = FAR_PTR(uw+1);
+
+ ireg.ebx.w[0] = PXENV_UDP_WRITE;
+ ireg.es = SEG(uw);
+ ireg.edi.w[0] = OFFS(uw);
+
+ __intcall(0x22, &ireg, &oreg);
+
+ start = times(NULL);
+
+ do {
+ memset(ur, 0, sizeof ur);
+ ur->src_ip = tftp->srv_ip;
+ ur->dest_ip = tftp->my_ip;
+ ur->s_port = tftp->srv_port;
+ ur->d_port = tftp->my_port;
+ ur->buffer_size = __com32.cs_bounce_size - sizeof *ur;
+ ur->buffer = FAR_PTR(ur+1);
+
+ ireg.ebx.w[0] = PXENV_UDP_READ;
+ ireg.es = SEG(ur);
+ ireg.edi.w[0] = OFFS(ur);
+ __intcall(0x22, &ireg, &oreg);
+
+ if (!(oreg.eflags.l & EFLAGS_CF) &&
+ ur->status == PXENV_STATUS_SUCCESS &&
+ tftp->srv_ip == ur->src_ip &&
+ (tftp->srv_port == 0 ||
+ tftp->srv_port == ur->s_port)) {
+ uint16_t *xb = (uint16_t *)(ur+1);
+ if (ntohs(xb[0]) == TFTP_ACK &&
+ ntohs(xb[1]) == tftp->seq) {
+ tftp->srv_port = ur->s_port;
+ return 0; /* All good! */
+ } else if (ntohs(xb[1]) == TFTP_ERROR) {
+ return -1; /* All bad! */
+ }
+ }
+ } while ((clock_t)(times(NULL) - start) < *timeout);
+ }
+
+ return -1; /* No success... */
+}
+
+static int be_tftp_write(struct backend *be)
+{
+ static uint16_t local_port = 0x4000;
+ struct tftp_state tftp;
+ char buffer[512+4+6];
+ int nlen;
+ const union syslinux_derivative_info *sdi =
+ syslinux_derivative_info();
+ const char *data = be->outbuf;
+ size_t len = be->zbytes;
+ size_t chunk;
+
+ tftp.my_ip = sdi->pxe.myip;
+ tftp.my_port = htons(local_port++);
+ tftp.srv_ip = pxe_dns(be->argv[1]);
+ tftp.srv_port = 0;
+ tftp.seq = 0;
+
+ buffer[0] = 0;
+ buffer[1] = TFTP_WRQ;
+ nlen = strlcpy(buffer+2, be->argv[0], 512);
+ memcpy(buffer+3+nlen, "octet", 6);
+
+ if (send_ack_packet(&tftp, buffer, 2+nlen+1+6))
+ return -1;
+
+ do {
+ chunk = len >= 512 ? 512 : len;
+
+ buffer[1] = TFTP_DATA;
+ *((uint16_t *)(buffer+2)) = htons(++tftp.seq);
+ memcpy(buffer+4, data, chunk);
+ data += chunk;
+ len -= chunk;
+
+ if (send_ack_packet(&tftp, buffer, chunk+4))
+ return -1;
+ } while (chunk == 512);
+
+ return 0;
+}
+
+struct backend be_tftp = {
+ .name = "tftp",
+ .helpmsg = "filename tftp_server",
+ .minargs = 2,
+ .write = be_tftp_write,
+};
diff --git a/com32/sysdump/be_ymodem.c b/com32/sysdump/be_ymodem.c
new file mode 100644
index 00000000..316b3d4e
--- /dev/null
+++ b/com32/sysdump/be_ymodem.c
@@ -0,0 +1,175 @@
+/*
+ * Ymodem send routine. Only supports 1K blocks and CRC mode.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include "backend.h"
+#include "serial.h"
+
+enum {
+ SOH = 0x01,
+ STX = 0x02,
+ EOT = 0x04,
+ ACK = 0x06,
+ NAK = 0x15,
+ CAN = 0x18,
+};
+
+struct ymodem_state {
+ struct serial_if serial;
+ unsigned int seq, blocks;
+};
+
+/*
+ * Append a CRC16 to a block
+ */
+static void add_crc16(uint8_t * blk, int len)
+{
+ static const uint16_t crctab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+ };
+ uint16_t crc = 0;
+
+ while (len--)
+ crc = crctab[(crc >> 8) ^ *blk++] ^ crc << 8;
+
+ *blk++ = crc >> 8;
+ *blk = crc;
+}
+
+static void send_ack(struct ymodem_state *ym, const uint8_t *blk,
+ size_t bytes);
+
+static void send_ack_blk(struct ymodem_state *ym, uint8_t *blk)
+{
+ printf("Sending block %u/%u...\r", ym->seq, ym->blocks);
+
+ blk[0] = STX;
+ blk[1] = ym->seq++;
+ blk[2] = ~blk[1];
+ add_crc16(blk+3, 1024);
+
+ send_ack(ym, blk, 1024+5);
+}
+
+static void send_ack(struct ymodem_state *ym, const uint8_t *blk, size_t bytes)
+{
+ uint8_t ack_buf;
+
+ do {
+ serial_write(&ym->serial, blk, bytes);
+
+ do {
+ serial_read(&ym->serial, &ack_buf, 1);
+ } while (ack_buf != ACK && ack_buf != NAK);
+ } while (ack_buf == NAK);
+}
+
+static int be_ymodem_write(struct backend *be)
+{
+ static const uint8_t eot_buf = EOT;
+ uint8_t ack_buf;
+ uint8_t blk_buf[1024 + 5];
+ struct ymodem_state ym;
+ const char *buf;
+ size_t len, chunk;
+ const char ymodem_banner[] = "Now begin Ymodem download...\r\n";
+
+ buf = be->outbuf;
+ len = be->zbytes;
+
+ putchar('\n');
+
+ ym.seq = 0;
+ ym.blocks = (len+1023)/1024;
+
+ /* Initialize serial port */
+ if (serial_init(&ym.serial, &be->argv[1]))
+ return -1;
+
+ /* Write banner */
+ printf("Writing banner...\n");
+ serial_write(&ym.serial, ymodem_banner, sizeof ymodem_banner-1);
+
+ /* Wait for initial handshake */
+ printf("Waiting for handshake...\n");
+ do {
+ serial_read(&ym.serial, &ack_buf, 1);
+ } while (ack_buf != 'C');
+
+ /* Send filename block */
+ memset(blk_buf, 0, sizeof blk_buf);
+ snprintf((char *)blk_buf+3, 1024, "%s%c%zu 0%o 0644",
+ be->argv[0], 0, be->zbytes, be->now);
+ send_ack_blk(&ym, blk_buf);
+
+ while (len) {
+ chunk = len < 1024 ? len : 1024;
+
+ memcpy(blk_buf+3, buf, chunk);
+ if (chunk < 1024)
+ memset(blk_buf+3+chunk, 0x1a, 1024-chunk);
+
+ send_ack_blk(&ym, blk_buf);
+ buf += chunk;
+ len -= chunk;
+ }
+
+ printf("\nSending EOT...\n");
+ send_ack(&ym, &eot_buf, 1);
+
+ printf("Waiting for handshake...\n");
+ do {
+ serial_read(&ym.serial, &ack_buf, 1);
+ } while (ack_buf != 'C');
+ ym.seq = 0;
+
+ printf("Sending batch termination block...\n");
+ memset(blk_buf+3, 0, 1024);
+ send_ack_blk(&ym, blk_buf);
+
+ printf("Cleaning up... \n");
+ serial_cleanup(&ym.serial);
+
+ return 0;
+}
+
+struct backend be_ymodem = {
+ .name = "ymodem",
+ .helpmsg = "filename [port [speed]]",
+ .minargs = 1,
+ .write = be_ymodem_write,
+};
diff --git a/com32/sysdump/cpio.c b/com32/sysdump/cpio.c
new file mode 100644
index 00000000..81d0d4be
--- /dev/null
+++ b/com32/sysdump/cpio.c
@@ -0,0 +1,75 @@
+/*
+ * cpio.c
+ *
+ * Write a compressed CPIO file
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "backend.h"
+#include "ctime.h"
+
+int cpio_pad(struct backend *be)
+{
+ static char pad[4]; /* Up to 4 zero bytes */
+ if (be->dbytes & 3)
+ return write_data(be, pad, -be->dbytes & 3);
+ else
+ return 0;
+}
+
+int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
+ const char *filename)
+{
+ static uint32_t inode = 2;
+ char hdr[6+13*8+1];
+ int nlen = strlen(filename)+1;
+ int rv = 0;
+
+ cpio_pad(be);
+
+ sprintf(hdr, "%06o%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
+ 070701, /* c_magic */
+ inode++, /* c_ino */
+ mode, /* c_mode */
+ 0, /* c_uid */
+ 0, /* c_gid */
+ 1, /* c_nlink */
+ be->now, /* c_mtime */
+ datalen, /* c_filesize */
+ 0, /* c_maj */
+ 0, /* c_min */
+ 0, /* c_rmaj */
+ 0, /* c_rmin */
+ nlen, /* c_namesize */
+ 0); /* c_chksum */
+ rv |= write_data(be, hdr, 6+13*8);
+ rv |= write_data(be, filename, nlen);
+ rv |= cpio_pad(be);
+ return rv;
+}
+
+int cpio_mkdir(struct backend *be, const char *filename)
+{
+ return cpio_hdr(be, MODE_DIR, 0, filename);
+}
+
+int cpio_writefile(struct backend *be, const char *filename,
+ const void *data, size_t len)
+{
+ int rv;
+
+ rv = cpio_hdr(be, MODE_FILE, len, filename);
+ rv |= write_data(be, data, len);
+ rv |= cpio_pad(be);
+
+ return rv;
+}
+
+int cpio_close(struct backend *be)
+{
+ return cpio_hdr(be, 0, 0, "TRAILER!!!");
+}
diff --git a/com32/sysdump/cpuid.c b/com32/sysdump/cpuid.c
new file mode 100644
index 00000000..40b20618
--- /dev/null
+++ b/com32/sysdump/cpuid.c
@@ -0,0 +1,112 @@
+/*
+ * Dump CPUID information
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <com32.h>
+#include <sys/cpu.h>
+#include "sysdump.h"
+#include "backend.h"
+
+struct cpuid_data {
+ uint32_t eax, ebx, ecx, edx;
+};
+
+struct cpuid_info {
+ uint32_t eax, ecx;
+ struct cpuid_data data;
+};
+
+static bool has_eflag(uint32_t flag)
+{
+ uint32_t f0, f1;
+
+ asm("pushfl ; "
+ "pushfl ; "
+ "popl %0 ; "
+ "movl %0,%1 ; "
+ "xorl %2,%1 ; "
+ "pushl %1 ; "
+ "popfl ; "
+ "pushfl ; "
+ "popl %1 ; "
+ "popfl"
+ : "=&r" (f0), "=&r" (f1)
+ : "ri" (flag));
+
+ return !!((f0^f1) & flag);
+}
+
+static inline void get_cpuid(uint32_t eax, uint32_t ecx,
+ struct cpuid_data *data)
+{
+ asm("cpuid"
+ : "=a" (data->eax), "=b" (data->ebx),
+ "=c" (data->ecx), "=d" (data->edx)
+ : "a" (eax), "c" (ecx));
+}
+
+#define CPUID_CHUNK 128
+
+void dump_cpuid(struct backend *be)
+{
+ struct cpuid_info *buf = NULL;
+ int nentry, nalloc;
+ uint32_t region;
+ struct cpuid_data base_leaf;
+ uint32_t base, leaf, count;
+ struct cpuid_data invalid_leaf;
+ struct cpuid_data data;
+
+ if (!has_eflag(EFLAGS_ID))
+ return;
+
+ printf("Dumping CPUID... ");
+
+ nentry = nalloc = 0;
+
+ /* Find out what the CPU returns for invalid leaves */
+ get_cpuid(0, 0, &base_leaf);
+ get_cpuid(base_leaf.eax+1, 0, &invalid_leaf);
+
+ for (region = 0 ; region <= 0xffff ; region++) {
+ base = region << 16;
+
+ get_cpuid(base, 0, &base_leaf);
+ if (region && !memcmp(&base_leaf, &invalid_leaf, sizeof base_leaf))
+ continue;
+
+ if ((base_leaf.eax ^ base) & 0xffff0000)
+ continue;
+
+ for (leaf = base ; leaf <= base_leaf.eax ; leaf++) {
+ get_cpuid(leaf, 0, &data);
+ count = 0;
+
+ do {
+ if (nentry >= nalloc) {
+ nalloc += CPUID_CHUNK;
+ buf = realloc(buf, nalloc*sizeof *buf);
+ if (!buf)
+ return; /* FAILED */
+ }
+ buf[nentry].eax = leaf;
+ buf[nentry].ecx = count;
+ buf[nentry].data = data;
+ nentry++;
+ count++;
+
+ get_cpuid(leaf, count, &data);
+ } while (memcmp(&data, &buf[nentry-1].data, sizeof data) &&
+ (data.eax | data.ebx | data.ecx | data.edx));
+ }
+ }
+
+ if (nentry)
+ cpio_writefile(be, "cpuid", buf, nentry*sizeof *buf);
+ free(buf);
+
+ printf("done.\n");
+}
diff --git a/com32/sysdump/ctime.c b/com32/sysdump/ctime.c
new file mode 100644
index 00000000..5af85666
--- /dev/null
+++ b/com32/sysdump/ctime.c
@@ -0,0 +1,70 @@
+#include <com32.h>
+#include <string.h>
+#include "ctime.h"
+
+static uint8_t frombcd(uint8_t v)
+{
+ uint8_t a = v & 0x0f;
+ uint8_t b = v >> 4;
+
+ return a + b*10;
+}
+
+uint32_t posix_time(void)
+{
+ /* Days from March 1 for a specific month, starting in March */
+ static const unsigned int yday[12] =
+ { 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 };
+ com32sys_t ir, d0, d1, t0;
+ unsigned int c, y, mo, d, h, m, s;
+ uint32_t t;
+
+ memset(&ir, 0, sizeof ir);
+
+ ir.eax.b[1] = 0x04;
+ __intcall(0x1A, &ir, &d0);
+
+ ir.eax.b[1] = 0x02;
+ __intcall(0x1A, &ir, &t0);
+
+ ir.eax.b[1] = 0x04;
+ __intcall(0x1A, &ir, &d1);
+
+ if (t0.ecx.b[1] < 0x12)
+ d0 = d1;
+
+ c = frombcd(d0.ecx.b[1]);
+ y = frombcd(d0.ecx.b[0]);
+ mo = frombcd(d0.edx.b[1]);
+ d = frombcd(d0.edx.b[0]);
+
+ h = frombcd(t0.ecx.b[1]);
+ m = frombcd(t0.ecx.b[0]);
+ s = frombcd(t0.edx.b[1]);
+
+ /* We of course have no idea about the timezone, so ignore it */
+
+ /*
+ * Look for impossible dates... this code was written in 2010, so
+ * assume any century less than 20 is just broken.
+ */
+ if (c < 20)
+ c = 20;
+ y += c*100;
+
+ /* Consider Jan and Feb as the last months of the previous year */
+ if (mo < 3) {
+ y--;
+ mo += 12;
+ }
+
+ t = y*365 + y/4 - y/100 + y/400 + yday[mo-3] + d - 719469;
+ t *= 24;
+ t += h;
+ t *= 60;
+ t += m;
+ t *= 60;
+ t += s;
+
+ return t;
+}
diff --git a/com32/sysdump/ctime.h b/com32/sysdump/ctime.h
new file mode 100644
index 00000000..e6461253
--- /dev/null
+++ b/com32/sysdump/ctime.h
@@ -0,0 +1,8 @@
+#ifndef CTIME_H
+#define CTIME_H
+
+#include <inttypes.h>
+
+uint32_t posix_time(void);
+
+#endif /* CTIME_H */
diff --git a/com32/sysdump/data.h b/com32/sysdump/data.h
new file mode 100644
index 00000000..deacf721
--- /dev/null
+++ b/com32/sysdump/data.h
@@ -0,0 +1,2 @@
+#ifndef DATA_H
+#define DATA_H
diff --git a/com32/sysdump/dmi.c b/com32/sysdump/dmi.c
new file mode 100644
index 00000000..be4cce46
--- /dev/null
+++ b/com32/sysdump/dmi.c
@@ -0,0 +1,126 @@
+/*
+ * Dump DMI information in a way hopefully compatible with dmidecode
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "sysdump.h"
+#include "backend.h"
+
+struct dmi_header {
+ char signature[5];
+ uint8_t csum;
+ uint16_t tbllen;
+ uint32_t tbladdr;
+ uint16_t nstruc;
+ uint8_t revision;
+ uint8_t reserved;
+};
+
+struct smbios_header {
+ char signature[4];
+ uint8_t csum;
+ uint8_t len;
+ uint8_t major;
+ uint8_t minor;
+ uint16_t maxsize;
+ uint8_t revision;
+ uint8_t fmt[5];
+
+ struct dmi_header dmi;
+};
+
+static uint8_t checksum(const void *buf, size_t len)
+{
+ const uint8_t *p = buf;
+ uint8_t csum = 0;
+
+ while (len--)
+ csum += *p++;
+
+ return csum;
+}
+
+static bool is_old_dmi(size_t dptr)
+{
+ const struct dmi_header *dmi = (void *)dptr;
+
+ return !memcmp(dmi->signature, "_DMI_", 5) &&
+ !checksum(dmi, 0x0f);
+ return false;
+}
+
+static bool is_smbios(size_t dptr)
+{
+ const struct smbios_header *smb = (void *)dptr;
+
+ return !memcmp(smb->signature, "_SM_", 4) &&
+ !checksum(smb, smb->len) &&
+ is_old_dmi(dptr+16);
+}
+
+static void dump_smbios(struct backend *be, size_t dptr)
+{
+ const struct smbios_header *smb = (void *)dptr;
+ struct smbios_header smx = *smb;
+ char filename[32];
+
+ snprintf(filename, sizeof filename, "dmi/%05x.%08x",
+ dptr, smb->dmi.tbladdr);
+ cpio_hdr(be, MODE_FILE, smb->dmi.tbllen + 32, filename);
+
+ /*
+ * Adjust the address of the smbios table to be 32, to
+ * make dmidecode happy. The checksum on the smbios table is unchanged,
+ * since it includes the checksum on the dmi table.
+ */
+ smx.dmi.tbladdr = sizeof smx;
+ smx.dmi.csum -= checksum(&smx.dmi, 0x0f);
+
+ write_data(be, &smx, sizeof smx);
+ write_data(be, (const void *)smb->dmi.tbladdr, smb->dmi.tbllen);
+}
+
+static void dump_old_dmi(struct backend *be, size_t dptr)
+{
+ const struct dmi_header *dmi = (void *)dptr;
+ struct fake {
+ struct dmi_header dmi;
+ char pad[16];
+ } fake;
+ char filename[32];
+
+ snprintf(filename, sizeof filename, "dmi/%05x.%08x",
+ dptr, dmi->tbladdr);
+ cpio_hdr(be, MODE_FILE, dmi->tbllen + 32, filename);
+
+ /*
+ * Adjust the address of the smbios table to be 32, to
+ * make dmidecode happy.
+ */
+ fake.dmi = *dmi;
+ memset(&fake.pad, 0, sizeof fake.pad);
+ fake.dmi.tbladdr = sizeof fake;
+ fake.dmi.csum -= checksum(&fake.dmi, 0x0f);
+
+ write_data(be, &fake, sizeof fake);
+ write_data(be, (const void *)dmi->tbladdr, dmi->tbllen);
+}
+
+void dump_dmi(struct backend *be)
+{
+ size_t dptr;
+
+ cpio_mkdir(be, "dmi");
+
+ /* Search for _SM_ or _DMI_ structure */
+ for (dptr = 0xf0000 ; dptr < 0x100000 ; dptr += 16) {
+ if (is_smbios(dptr)) {
+ dump_smbios(be, dptr);
+ dptr += 16; /* Skip the subsequent DMI header */
+ } else if (is_old_dmi(dptr)) {
+ dump_old_dmi(be, dptr);
+ }
+ }
+}
diff --git a/com32/sysdump/main.c b/com32/sysdump/main.c
new file mode 100644
index 00000000..d4a0320e
--- /dev/null
+++ b/com32/sysdump/main.c
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * 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,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <dprintf.h>
+#include <console.h>
+#include <sys/cpu.h>
+#include "../../version.h"
+#include "backend.h"
+#include "sysdump.h"
+
+const char program[] = "sysdump";
+const char version[] = "SYSDUMP " VERSION_STR " " DATE "\n";
+
+__noreturn die(const char *msg)
+{
+ printf("%s: %s\n", program, msg);
+ exit(1);
+}
+
+static void dump_all(struct backend *be, const char *argv[])
+{
+ cpio_init(be, argv);
+
+ cpio_writefile(be, "sysdump", version, sizeof version-1);
+
+ dump_memory_map(be);
+ dump_memory(be);
+ dump_dmi(be);
+ dump_cpuid(be);
+ dump_pci(be);
+ dump_vesa_tables(be);
+
+ cpio_close(be);
+ flush_data(be);
+}
+
+static struct backend *backends[] =
+{
+ &be_tftp,
+ &be_ymodem,
+ NULL
+};
+
+__noreturn usage(void)
+{
+ struct backend **bep, *be;
+
+ printf("Usage:\n");
+ for (bep = backends ; (be = *bep) ; bep++)
+ printf(" %s %s %s\n", program, be->name, be->helpmsg);
+
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ struct backend **bep, *be;
+
+ openconsole(&dev_null_r, &dev_stdcon_w);
+ fputs(version, stdout);
+
+ if (argc < 2)
+ usage();
+
+ for (bep = backends ; (be = *bep) ; bep++) {
+ if (!strcmp(be->name, argv[1]))
+ break;
+ }
+
+ if (!be || argc < be->minargs + 2)
+ usage();
+
+ /* Do this as early as possible */
+ snapshot_lowmem();
+
+ printf("Backend: %s\n", be->name);
+
+ /* Do the actual data dump */
+ dump_all(be, (const char **)argv + 2);
+
+ return 0;
+}
diff --git a/com32/sysdump/memmap.c b/com32/sysdump/memmap.c
new file mode 100644
index 00000000..a85f0925
--- /dev/null
+++ b/com32/sysdump/memmap.c
@@ -0,0 +1,81 @@
+/*
+ * Dump memory map information
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <com32.h>
+#include "sysdump.h"
+#include "backend.h"
+
+#define E820_CHUNK 128
+struct e820_info {
+ uint32_t ebx;
+ uint32_t len;
+ uint8_t data[24];
+};
+
+static void dump_e820(struct backend *be)
+{
+ com32sys_t ireg, oreg;
+ struct e820_info *curr = __com32.cs_bounce;
+ struct e820_info *buf, *p;
+ int nentry, nalloc;
+
+ buf = p = NULL;
+ nentry = nalloc = 0;
+ memset(&ireg, 0, sizeof ireg);
+ memset(&curr, 0, sizeof curr);
+
+ ireg.eax.l = 0xe820;
+ ireg.edx.l = 0x534d4150;
+ ireg.ecx.l = sizeof curr->data;
+ ireg.es = SEG(curr->data);
+ ireg.edi.w[0] = OFFS(curr->data);
+
+ do {
+ __intcall(0x15, &ireg, &oreg);
+ if ((oreg.eflags.l & EFLAGS_CF) ||
+ oreg.eax.l != 0x534d4150)
+ break;
+
+ if (nentry >= nalloc) {
+ nalloc += E820_CHUNK;
+ buf = realloc(buf, nalloc*sizeof *buf);
+ if (!buf)
+ return; /* FAILED */
+ }
+ memcpy(buf[nentry].data, curr->data, sizeof curr->data);
+ buf[nentry].ebx = ireg.ebx.l;
+ buf[nentry].len = oreg.ecx.l;
+ nentry++;
+
+ ireg.ebx.l = oreg.ebx.l;
+ } while (ireg.ebx.l);
+
+ if (nentry)
+ cpio_writefile(be, "memmap/15e820", buf, nentry*sizeof *buf);
+ free(buf);
+}
+
+void dump_memory_map(struct backend *be)
+{
+ com32sys_t ireg, oreg;
+
+ cpio_mkdir(be, "memmap");
+
+ memset(&ireg, 0, sizeof ireg);
+ __intcall(0x12, &ireg, &oreg);
+ cpio_writefile(be, "memmap/12", &oreg, sizeof oreg);
+
+ ireg.eax.b[1] = 0x88;
+ __intcall(0x15, &ireg, &oreg);
+ cpio_writefile(be, "memmap/1588", &oreg, sizeof oreg);
+
+ ireg.eax.w[0] = 0xe801;
+ __intcall(0x15, &ireg, &oreg);
+ cpio_writefile(be, "memmap/15e801", &oreg, sizeof oreg);
+
+ dump_e820(be);
+}
diff --git a/com32/sysdump/memory.c b/com32/sysdump/memory.c
new file mode 100644
index 00000000..6552e7f3
--- /dev/null
+++ b/com32/sysdump/memory.c
@@ -0,0 +1,51 @@
+/*
+ * Dump memory
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/cpu.h>
+#include "sysdump.h"
+#include "backend.h"
+
+static char *lowmem;
+static size_t lowmem_len;
+
+void *zero_addr; /* Hack to keep gcc from complaining */
+
+void snapshot_lowmem(void)
+{
+ extern void _start(void);
+
+ lowmem_len = (size_t)_start;
+ lowmem = malloc(lowmem_len);
+ if (lowmem) {
+ printf("Snapshotting lowmem... ");
+ cli();
+ memcpy(lowmem, zero_addr, lowmem_len);
+ sti();
+ printf("ok\n");
+ }
+}
+
+static void dump_memory_range(struct backend *be, const void *where,
+ const void *addr, size_t len)
+{
+ char filename[32];
+
+ sprintf(filename, "memory/%08zx", (size_t)addr);
+ cpio_writefile(be, filename, where, len);
+}
+
+void dump_memory(struct backend *be)
+{
+ printf("Dumping memory... ");
+
+ cpio_mkdir(be, "memory");
+
+ if (lowmem)
+ dump_memory_range(be, lowmem, zero_addr, lowmem_len);
+
+ printf("done.\n");
+}
diff --git a/com32/sysdump/pci.c b/com32/sysdump/pci.c
new file mode 100644
index 00000000..1d687279
--- /dev/null
+++ b/com32/sysdump/pci.c
@@ -0,0 +1,70 @@
+/*
+ * Dump PCI device headers
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/pci.h>
+#include "sysdump.h"
+#include "backend.h"
+
+static void dump_pci_device(struct backend *be, pciaddr_t a, uint8_t hdrtype)
+{
+ unsigned int bus = pci_bus(a);
+ unsigned int dev = pci_dev(a);
+ unsigned int func = pci_func(a);
+ uint8_t data[256];
+ unsigned int i;
+ char filename[32];
+
+ hdrtype &= 0x7f;
+
+ printf("Scanning PCI bus... %02x:%02x.%x\r", bus, dev, func);
+
+ /* Assume doing a full device dump is actually safe... */
+ for (i = 0; i < sizeof data; i += 4)
+ *(uint32_t *)(data+i) = pci_readl(a + i);
+
+ snprintf(filename, sizeof filename, "pci/%02x:%02x.%x",
+ bus, dev, func);
+ cpio_writefile(be, filename, data, sizeof data);
+}
+
+void dump_pci(struct backend *be)
+{
+ int cfgtype;
+ unsigned int nbus, ndev, nfunc, maxfunc;
+ pciaddr_t a;
+ uint32_t did;
+ uint8_t hdrtype;
+
+ cfgtype = pci_set_config_type(PCI_CFG_AUTO);
+ if (cfgtype == PCI_CFG_NONE)
+ return;
+
+ cpio_mkdir(be, "pci");
+
+ for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) {
+ for (ndev = 0; ndev < MAX_PCI_DEVICES; ndev++) {
+ maxfunc = 1; /* Assume a single-function device */
+
+ for (nfunc = 0; nfunc < maxfunc; nfunc++) {
+ a = pci_mkaddr(nbus, ndev, nfunc, 0);
+ did = pci_readl(a);
+
+ if (did == 0xffffffff || did == 0xffff0000 ||
+ did == 0x0000ffff || did == 0x00000000)
+ continue;
+
+ hdrtype = pci_readb(a + 0x0e);
+ if (hdrtype & 0x80)
+ maxfunc = MAX_PCI_FUNC; /* Multifunction device */
+
+ dump_pci_device(be, a, hdrtype);
+ }
+ }
+ }
+
+ printf("Scanning PCI bus... done. \n");
+}
diff --git a/com32/sysdump/serial.c b/com32/sysdump/serial.c
new file mode 100644
index 00000000..a3987531
--- /dev/null
+++ b/com32/sysdump/serial.c
@@ -0,0 +1,169 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+#include <syslinux/config.h>
+
+#include "serial.h"
+
+enum {
+ THR = 0,
+ RBR = 0,
+ DLL = 0,
+ DLM = 1,
+ IER = 1,
+ IIR = 2,
+ FCR = 2,
+ LCR = 3,
+ MCR = 4,
+ LSR = 5,
+ MSR = 6,
+ SCR = 7,
+};
+
+
+int serial_init(struct serial_if *sif, const char *argv[])
+{
+ const struct syslinux_serial_console_info *sci
+ = syslinux_serial_console_info();
+ uint16_t port;
+ unsigned int divisor;
+ uint8_t dll, dlm, lcr;
+
+ if (!argv[0]) {
+ if (sci->iobase) {
+ port = sci->iobase;
+ } else {
+ printf("No port number specified and not using serial console!\n");
+ return -1;
+ }
+ } else {
+ port = strtoul(argv[0], NULL, 0);
+ if (port <= 3) {
+ uint16_t addr = ((uint16_t *)0x400)[port];
+ if (!addr) {
+ printf("No serial port address found!\n");
+ return -1;
+ }
+ printf("Serial port %u is at 0x%04x\n", port, addr);
+ port = addr;
+ }
+ }
+
+ sif->port = port;
+ sif->console = false;
+
+ divisor = 1; /* Default speed = 115200 bps */
+
+ /* Check to see if this is the same as the serial console */
+ if (port == sci->iobase) {
+ /* Overlaying the console... */
+ sif->console = true;
+
+ /* Default to already configured speed */
+ divisor = sci->divisor;
+
+ /* Shut down I/O to the console for the time being */
+ openconsole(&dev_null_r, &dev_null_w);
+ }
+
+ if (argv[0] && argv[1])
+ divisor = 115200/strtoul(argv[1], NULL, 0);
+
+ cli(); /* Just in case... */
+
+ /* Save old register settings */
+ sif->old.lcr = inb(port + LCR);
+ sif->old.mcr = inb(port + MCR);
+ sif->old.iir = inb(port + IIR);
+
+ /* Set speed */
+ outb(0x83, port + LCR); /* Enable divisor access */
+ sif->old.dll = inb(port + DLL);
+ sif->old.dlm = inb(port + DLM);
+ outb(divisor, port + DLL);
+ outb(divisor >> 8, port + DLM);
+ (void)inb(port + IER); /* Synchronize */
+
+ dll = inb(port + DLL);
+ dlm = inb(port + DLM);
+ lcr = inb(port + LCR);
+ outb(0x03, port + LCR); /* Enable data access, n81 */
+ (void)inb(port + IER); /* Synchronize */
+ sif->old.ier = inb(port + IER);
+
+ /* Disable interrupts */
+ outb(0, port + IER);
+
+ sti();
+
+ if (dll != (uint8_t)divisor ||
+ dlm != (uint8_t)(divisor >> 8) ||
+ lcr != 0x83) {
+ serial_cleanup(sif);
+ printf("No serial port detected!\n");
+ return -1; /* This doesn't look like a serial port */
+ }
+
+ /* Enable 16550A FIFOs if available */
+ outb(0x01, port + FCR); /* Enable FIFO */
+ (void)inb(port + IER); /* Synchronize */
+ if (inb(port + IIR) < 0xc0)
+ outb(0x00, port + FCR); /* Disable FIFOs if non-functional */
+ (void)inb(port + IER); /* Synchronize */
+
+ return 0;
+}
+
+void serial_write(struct serial_if *sif, const void *data, size_t n)
+{
+ uint16_t port = sif->port;
+ const char *p = data;
+ uint8_t lsr;
+
+ while (n--) {
+ do {
+ lsr = inb(port + LSR);
+ } while (!(lsr & 0x20));
+
+ outb(*p++, port + THR);
+ }
+}
+
+void serial_read(struct serial_if *sif, void *data, size_t n)
+{
+ uint16_t port = sif->port;
+ char *p = data;
+ uint8_t lsr;
+
+ while (n--) {
+ do {
+ lsr = inb(port + LSR);
+ } while (!(lsr & 0x01));
+
+ *p++ = inb(port + RBR);
+ }
+}
+
+void serial_cleanup(struct serial_if *sif)
+{
+ uint16_t port = sif->port;
+
+ outb(0x83, port + LCR);
+ (void)inb(port + IER);
+ outb(sif->old.dll, port + DLL);
+ outb(sif->old.dlm, port + DLM);
+ (void)inb(port + IER);
+ outb(sif->old.lcr & 0x7f, port + LCR);
+ (void)inb(port + IER);
+ outb(sif->old.mcr, port + MCR);
+ outb(sif->old.ier, port + IER);
+ if (sif->old.iir < 0xc0)
+ outb(0x00, port + FCR); /* Disable FIFOs */
+
+ /* Re-enable console messages, if we shut them down */
+ if (sif->console)
+ openconsole(&dev_null_r, &dev_stdcon_w);
+}
diff --git a/com32/sysdump/serial.h b/com32/sysdump/serial.h
new file mode 100644
index 00000000..356f2cef
--- /dev/null
+++ b/com32/sysdump/serial.h
@@ -0,0 +1,19 @@
+#ifndef SERIAL_H
+#define SERIAL_H
+
+#include <stddef.h>
+
+struct serial_if {
+ uint16_t port;
+ bool console;
+ struct {
+ uint8_t dll, dlm, ier, iir, lcr, mcr;
+ } old;
+};
+
+int serial_init(struct serial_if *sif, const char *argv[]);
+void serial_read(struct serial_if *sif, void *data, size_t n);
+void serial_write(struct serial_if *sif, const void *data, size_t n);
+void serial_cleanup(struct serial_if *sif);
+
+#endif /* SERIAL_H */
diff --git a/com32/sysdump/srecsend.h b/com32/sysdump/srecsend.h
new file mode 100644
index 00000000..667be20d
--- /dev/null
+++ b/com32/sysdump/srecsend.h
@@ -0,0 +1,9 @@
+#ifndef SRECSEND_H
+#define SRECSEND_H
+
+#include "file.h"
+
+void send_srec(struct serial_if *, struct file_info *,
+ void (*)(void *, size_t, struct file_info *, size_t));
+
+#endif /* SRECSEND_H */
diff --git a/com32/sysdump/sysdump.h b/com32/sysdump/sysdump.h
new file mode 100644
index 00000000..61a04a2b
--- /dev/null
+++ b/com32/sysdump/sysdump.h
@@ -0,0 +1,14 @@
+#ifndef SYSDUMP_H
+#define SYSDUMP_H
+
+struct backend;
+
+void dump_memory_map(struct backend *);
+void snapshot_lowmem(void);
+void dump_memory(struct backend *);
+void dump_dmi(struct backend *);
+void dump_cpuid(struct backend *);
+void dump_pci(struct backend *);
+void dump_vesa_tables(struct backend *);
+
+#endif /* SYSDUMP_H */
diff --git a/com32/sysdump/vesa.c b/com32/sysdump/vesa.c
new file mode 100644
index 00000000..9bdc7153
--- /dev/null
+++ b/com32/sysdump/vesa.c
@@ -0,0 +1,60 @@
+#include <string.h>
+#include <stdio.h>
+#include "../lib/sys/vesa/vesa.h"
+#include "backend.h"
+#include "sysdump.h"
+
+void dump_vesa_tables(struct backend *be)
+{
+ com32sys_t rm;
+ struct vesa_general_info *gip, gi;
+ struct vesa_mode_info *mip, mi;
+ uint16_t mode, *mode_ptr;
+ char modefile[64];
+
+ printf("Scanning VESA BIOS... ");
+
+ /* Allocate space in the bounce buffer for these structures */
+ gip = &((struct vesa_info *)__com32.cs_bounce)->gi;
+ mip = &((struct vesa_info *)__com32.cs_bounce)->mi;
+
+ memset(&rm, 0, sizeof rm);
+ memset(gip, 0, sizeof *gip);
+
+ gip->signature = VBE2_MAGIC; /* Get VBE2 extended data */
+ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */
+ rm.edi.w[0] = OFFS(gip);
+ rm.es = SEG(gip);
+ __intcall(0x10, &rm, &rm);
+ memcpy(&gi, gip, sizeof gi);
+
+ if (rm.eax.w[0] != 0x004F)
+ return; /* Function call failed */
+ if (gi.signature != VESA_MAGIC)
+ return; /* No magic */
+
+ cpio_mkdir(be, "vesa");
+
+ cpio_writefile(be, "vesa/global.bin", &gi, sizeof gi);
+
+ mode_ptr = GET_PTR(gi.video_mode_ptr);
+ while ((mode = *mode_ptr++) != 0xFFFF) {
+ memset(mip, 0, sizeof *mip);
+ rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */
+ rm.ecx.w[0] = mode;
+ rm.edi.w[0] = OFFS(mip);
+ rm.es = SEG(mip);
+ __intcall(0x10, &rm, &rm);
+
+ /* Must be a supported mode */
+ if (rm.eax.w[0] != 0x004f)
+ continue;
+
+ memcpy(&mi, mip, sizeof mi);
+
+ sprintf(modefile, "vesa/mode%04x.bin", mode);
+ cpio_writefile(be, modefile, &mi, sizeof mi);
+ }
+
+ printf("done.\n");
+}
diff --git a/com32/sysdump/ymodem.txt b/com32/sysdump/ymodem.txt
new file mode 100644
index 00000000..2264ff78
--- /dev/null
+++ b/com32/sysdump/ymodem.txt
@@ -0,0 +1,2108 @@
+
+
+
+ - 1 -
+
+
+
+ XMODEM/YMODEM PROTOCOL REFERENCE
+ A compendium of documents describing the
+
+ XMODEM and YMODEM
+
+ File Transfer Protocols
+
+
+
+
+ This document was formatted 10-14-88.
+
+
+
+
+
+
+
+ Edited by Chuck Forsberg
+
+
+
+
+
+
+
+
+
+ This file may be redistributed without restriction
+ provided the text is not altered.
+
+ Please distribute as widely as possible.
+
+ Questions to Chuck Forsberg
+
+
+
+
+
+ Omen Technology Inc
+ The High Reliability Software
+ 17505-V Sauvie Island Road
+ Portland Oregon 97231
+ VOICE: 503-621-3406 :VOICE
+ TeleGodzilla BBS: 503-621-3746 Speed 19200(Telebit PEP),2400,1200,300
+ CompuServe: 70007,2304
+ GEnie: CAF
+ UUCP: ...!tektronix!reed!omen!caf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - 2 -
+
+
+
+ 1. TOWER OF BABEL
+
+ A "YMODEM Tower of Babel" has descended on the microcomputing community
+ bringing with it confusion, frustration, bloated phone bills, and wasted
+ man hours. Sadly, I (Chuck Forsberg) am partly to blame for this mess.
+
+ As author of the early 1980s batch and 1k XMODEM extensions, I assumed
+ readers of earlier versions of this document would implement as much of
+ the YMODEM protocol as their programming skills and computing environments
+ would permit. This proved a rather naive assumption as programmers
+ motivated by competitive pressure implemented as little of YMODEM as
+ possible. Some have taken whatever parts of YMODEM that appealed to them,
+ applied them to MODEM7 Batch, Telink, XMODEM or whatever, and called the
+ result YMODEM.
+
+ Jeff Garbers (Crosstalk package development director) said it all: "With
+ protocols in the public domain, anyone who wants to dink around with them
+ can go ahead." [1]
+
+ Documents containing altered examples derived from YMODEM.DOC have added
+ to the confusion. In one instance, some self styled rewriter of history
+ altered the heading in YMODEM.DOC's Figure 1 from "1024 byte Packets" to
+ "YMODEM/CRC File Transfer Protocol". None of the XMODEM and YMODEM
+ examples shown in that document were correct.
+
+ To put an end to this confusion, we must make "perfectly clear" what
+ YMODEM stands for, as Ward Christensen defined it in his 1985 coining of
+ the term.
+
+ To the majority of you who read, understood, and respected Ward's
+ definition of YMODEM, I apologize for the inconvenience.
+
+ 1.1 Definitions
+
+ ARC ARC is a program that compresses one or more files into an archive
+ and extracts files from such archives.
+
+ XMODEM refers to the file transfer etiquette introduced by Ward
+ Christensen's 1977 MODEM.ASM program. The name XMODEM comes from
+ Keith Petersen's XMODEM.ASM program, an adaptation of MODEM.ASM
+ for Remote CP/M (RCPM) systems. It's also called the MODEM or
+ MODEM2 protocol. Some who are unaware of MODEM7's unusual batch
+ file mode call it MODEM7. Other aliases include "CP/M Users'
+ Group" and "TERM II FTP 3". The name XMODEM caught on partly
+ because it is distinctive and partly because of media interest in
+
+
+ __________
+
+ 1. Page C/12, PC-WEEK July 12, 1987
+
+
+
+
+ Chapter 1
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 3
+
+
+
+ bulletin board and RCPM systems where it was accessed with an
+ "XMODEM" command. This protocol is supported by every serious
+ communications program because of its universality, simplicity,
+ and reasonable performance.
+
+ XMODEM/CRC replaces XMODEM's 1 byte checksum with a two byte Cyclical
+ Redundancy Check (CRC-16), giving modern error detection
+ protection.
+
+ XMODEM-1k Refers to the XMODEM/CRC protocol with 1024 byte data blocks.
+
+ YMODEM Refers to the XMODEM/CRC (optional 1k blocks) protocol with batch
+ transmission as described below. In a nutshell, YMODEM means
+ BATCH.
+
+ YMODEM-g Refers to the streaming YMODEM variation described below.
+
+ True YMODEM(TM) In an attempt to sort out the YMODEM Tower of Babel, Omen
+ Technology has trademarked the term True YMODEM(TM) to represent
+ the complete YMODEM protocol described in this document, including
+ pathname, length, and modification date transmitted in block 0.
+ Please contact Omen Technology about certifying programs for True
+ YMODEM(TM) compliance.
+
+ ZMODEM uses familiar XMODEM/CRC and YMODEM technology in a new protocol
+ that provides reliability, throughput, file management, and user
+ amenities appropriate to contemporary data communications.
+
+ ZOO Like ARC, ZOO is a program that compresses one or more files into
+ a "zoo archive". ZOO supports many different operating systems
+ including Unix and VMS.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 1
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 4
+
+
+
+ 2. YMODEM MINIMUM REQUIREMENTS
+
+ All programs claiming to support YMODEM must meet the following minimum
+ requirements:
+
+ + The sending program shall send the pathname (file name) in block 0.
+
+ + The pathname shall be a null terminated ASCII string as described
+ below.
+
+ For those who are too lazy to read the entire document:
+
+ + Unless specifically requested, only the file name portion is
+ sent.
+
+ + No drive letter is sent.
+
+ + Systems that do not distinguish between upper and lower case
+ letters in filenames shall send the pathname in lower case only.
+
+
+ + The receiving program shall use this pathname for the received file
+ name, unless explicitly overridden.
+
+ + When the receiving program receives this block and successfully
+ opened the output file, it shall acknowledge this block with an ACK
+ character and then proceed with a normal XMODEM file transfer
+ beginning with a "C" or NAK tranmsitted by the receiver.
+
+ + The sending program shall use CRC-16 in response to a "C" pathname
+ nak, otherwise use 8 bit checksum.
+
+ + The receiving program must accept any mixture of 128 and 1024 byte
+ blocks within each file it receives. Sending programs may
+ arbitrarily switch between 1024 and 128 byte blocks.
+
+ + The sending program must not change the length of an unacknowledged
+ block.
+
+ + At the end of each file, the sending program shall send EOT up to ten
+ times until it receives an ACK character. (This is part of the
+ XMODEM spec.)
+
+ + The end of a transfer session shall be signified by a null (empty)
+ pathname, this pathname block shall be acknowledged the same as other
+ pathname blocks.
+
+ Programs not meeting all of these requirements are not YMODEM compatible,
+ and shall not be described as supporting YMODEM.
+
+ Meeting these MINIMUM requirements does not guarantee reliable file
+
+
+
+ Chapter 2
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 5
+
+
+
+ transfers under stress. Particular attention is called to XMODEM's single
+ character supervisory messages that are easily corrupted by transmission
+ errors.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 2
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 6
+
+
+
+ 3. WHY YMODEM?
+
+ Since its development half a decade ago, the Ward Christensen modem
+ protocol has enabled a wide variety of computer systems to interchange
+ data. There is hardly a communications program that doesn't at least
+ claim to support this protocol.
+
+ Advances in computing, modems and networking have revealed a number of
+ weaknesses in the original protocol:
+
+ + The short block length caused throughput to suffer when used with
+ timesharing systems, packet switched networks, satellite circuits,
+ and buffered (error correcting) modems.
+
+ + The 8 bit arithmetic checksum and other aspects allowed line
+ impairments to interfere with dependable, accurate transfers.
+
+ + Only one file could be sent per command. The file name had to be
+ given twice, first to the sending program and then again to the
+ receiving program.
+
+ + The transmitted file could accumulate as many as 127 extraneous
+ bytes.
+
+ + The modification date of the file was lost.
+
+ A number of other protocols have been developed over the years, but none
+ have displaced XMODEM to date:
+
+ + Lack of public domain documentation and example programs have kept
+ proprietary protocols such as Blast, Relay, and others tightly bound
+ to the fortunes of their suppliers.
+
+ + Complexity discourages the widespread application of BISYNC, SDLC,
+ HDLC, X.25, and X.PC protocols.
+
+ + Performance compromises and complexity have limited the popularity of
+ the Kermit protocol, which was developed to allow file transfers in
+ environments hostile to XMODEM.
+
+ The XMODEM protocol extensions and YMODEM Batch address some of these
+ weaknesses while maintaining most of XMODEM's simplicity.
+
+ YMODEM is supported by the public domain programs YAM (CP/M),
+ YAM(CP/M-86), YAM(CCPM-86), IMP (CP/M), KMD (CP/M), rz/sz (Unix, Xenix,
+ VMS, Berkeley Unix, Venix, Xenix, Coherent, IDRIS, Regulus). Commercial
+ implementations include MIRROR, and Professional-YAM.[1] Communications
+
+
+
+
+
+
+
+ Chapter 3
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 7
+
+
+
+ programs supporting these extensions have been in use since 1981.
+
+ The 1k block length (XMODEM-1k) described below may be used in conjunction
+ with YMODEM Batch Protocol, or with single file transfers identical to the
+ XMODEM/CRC protocol except for minimal changes to support 1k blocks.
+
+ Another extension is the YMODEM-g protocol. YMODEM-g provides batch
+ transfers with maximum throughput when used with end to end error
+ correcting media, such as X.PC and error correcting modems, including 9600
+ bps units by TeleBit, U.S.Robotics, Hayes, Electronic Vaults, Data Race,
+ and others.
+
+ To complete this tome, edited versions of Ward Christensen's original
+ protocol document and John Byrns's CRC-16 document are included for
+ reference.
+
+ References to the MODEM or MODEM7 protocol have been changed to XMODEM to
+ accommodate the vernacular. In Australia, it is properly called the
+ Christensen Protocol.
+
+
+ 3.1 Some Messages from the Pioneer
+
+ #: 130940 S0/Communications 25-Apr-85 18:38:47
+ Sb: my protocol
+ Fm: Ward Christensen 76703,302 [2]
+ To: all
+
+ Be aware the article[3] DID quote me correctly in terms of the phrases
+ like "not robust", etc.
+
+ It was a quick hack I threw together, very unplanned (like everything I
+ do), to satisfy a personal need to communicate with "some other" people.
+
+ ONLY the fact that it was done in 8/77, and that I put it in the public
+ domain immediately, made it become the standard that it is.
+
+
+
+
+
+
+
+ __________________________________________________________________________
+
+ 1. Available for IBM PC,XT,AT, Unix and Xenix
+
+ 2. Edited for typesetting appearance
+
+ 3. Infoworld April 29 p. 16
+
+
+
+
+ Chapter 3
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 8
+
+
+
+ I think its time for me to
+
+ (1) document it; (people call me and say "my product is going to include
+ it - what can I 'reference'", or "I'm writing a paper on it, what do I put
+ in the bibliography") and
+
+ (2) propose an "incremental extension" to it, which might take "exactly"
+ the form of Chuck Forsberg's YAM protocol. He wrote YAM in C for CP/M and
+ put it in the public domain, and wrote a batch protocol for Unix[4] called
+ rb and sb (receive batch, send batch), which was basically XMODEM with
+ (a) a record 0 containing filename date time and size
+ (b) a 1K block size option
+ (c) CRC-16.
+
+ He did some clever programming to detect false ACK or EOT, but basically
+ left them the same.
+
+ People who suggest I make SIGNIFICANT changes to the protocol, such as
+ "full duplex", "multiple outstanding blocks", "multiple destinations", etc
+ etc don't understand that the incredible simplicity of the protocol is one
+ of the reasons it survived to this day in as many machines and programs as
+ it may be found in!
+
+ Consider the PC-NET group back in '77 or so - documenting to beat the band
+ - THEY had a protocol, but it was "extremely complex", because it tried to
+ be "all things to all people" - i.e. send binary files on a 7-bit system,
+ etc. I was not that "benevolent". I (emphasize > I < ) had an 8-bit UART,
+ so "my protocol was an 8-bit protocol", and I would just say "sorry" to
+ people who were held back by 7-bit limitations. ...
+
+ Block size: Chuck Forsberg created an extension of my protocol, called
+ YAM, which is also supported via his public domain programs for UNIX
+ called rb and sb - receive batch and send batch. They cleverly send a
+ "block 0" which contains the filename, date, time, and size.
+ Unfortunately, its UNIX style, and is a bit weird[5] - octal numbers, etc.
+ BUT, it is a nice way to overcome the kludgy "echo the chars of the name"
+ introduced with MODEM7. Further, chuck uses CRC-16 and optional 1K
+ blocks. Thus the record 0, 1K, and CRC, make it a "pretty slick new
+ protocol" which is not significantly different from my own.
+
+ Also, there is a catchy name - YMODEM. That means to some that it is the
+ "next thing after XMODEM", and to others that it is the Y(am)MODEM
+
+
+ __________
+
+ 4. VAX/VMS versions of these programs are also available.
+
+ 5. The file length, time, and file mode are optional. The pathname and
+ file length may be sent alone if desired.
+
+
+
+
+ Chapter 3
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 9
+
+
+
+ protocol. I don't want to emphasize that too much - out of fear that
+ other mfgrs might think it is a "competitive" protocol, rather than an
+ "unaffiliated" protocol. Chuck is currently selling a much-enhanced
+ version of his CP/M-80 C program YAM, calling it Professional Yam, and its
+ for the PC - I'm using it right now. VERY slick! 32K capture buffer,
+ script, scrolling, previously captured text search, plus built-in commands
+ for just about everything - directory (sorted every which way), XMODEM,
+ YMODEM, KERMIT, and ASCII file upload/download, etc. You can program it
+ to "behave" with most any system - for example when trying a number for
+ CIS it detects the "busy" string back from the modem and substitutes a
+ diff phone # into the dialing string and branches back to try it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 3
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 10
+
+
+
+ 4. XMODEM PROTOCOL ENHANCEMENTS
+
+ This chapter discusses the protocol extensions to Ward Christensen's 1982
+ XMODEM protocol description document.
+
+ The original document recommends the user be asked whether to continue
+ trying or abort after 10 retries. Most programs no longer ask the
+ operator whether he wishes to keep retrying. Virtually all correctable
+ errors are corrected within the first few retransmissions. If the line is
+ so bad that ten attempts are insufficient, there is a significant danger
+ of undetected errors. If the connection is that bad, it's better to
+ redial for a better connection, or mail a floppy disk.
+
+
+ 4.1 Graceful Abort
+
+ The YAM and Professional-YAM X/YMODEM routines recognize a sequence of two
+ consecutive CAN (Hex 18) characters without modem errors (overrun,
+ framing, etc.) as a transfer abort command. This sequence is recognized
+ when is waiting for the beginning of a block or for an acknowledgement to
+ a block that has been sent. The check for two consecutive CAN characters
+ reduces the number of transfers aborted by line hits. YAM sends eight CAN
+ characters when it aborts an XMODEM, YMODEM, or ZMODEM protocol file
+ transfer. Pro-YAM then sends eight backspaces to delete the CAN
+ characters from the remote's keyboard input buffer, in case the remote had
+ already aborted the transfer and was awaiting a keyboarded command.
+
+
+ 4.2 CRC-16 Option
+
+ The XMODEM protocol uses an optional two character CRC-16 instead of the
+ one character arithmetic checksum used by the original protocol and by
+ most commercial implementations. CRC-16 guarantees detection of all
+ single and double bit errors, all errors with an odd number of error
+ bits, all burst errors of length 16 or less, 99.9969% of all 17-bit error
+ bursts, and 99.9984 per cent of all possible longer error bursts. By
+ contrast, a double bit error, or a burst error of 9 bits or more can sneak
+ past the XMODEM protocol arithmetic checksum.
+
+ The XMODEM/CRC protocol is similar to the XMODEM protocol, except that the
+ receiver specifies CRC-16 by sending C (Hex 43) instead of NAK when
+ requesting the FIRST block. A two byte CRC is sent in place of the one
+ byte arithmetic checksum.
+
+ YAM's c option to the r command enables CRC-16 in single file reception,
+ corresponding to the original implementation in the MODEM7 series
+ programs. This remains the default because many commercial communications
+ programs and bulletin board systems still do not support CRC-16,
+ especially those written in Basic or Pascal.
+
+ XMODEM protocol with CRC is accurate provided both sender and receiver
+
+
+
+ Chapter 4 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 11
+
+
+
+ both report a successful transmission. The protocol is robust in the
+ presence of characters lost by buffer overloading on timesharing systems.
+
+ The single character ACK/NAK responses generated by the receiving program
+ adapt well to split speed modems, where the reverse channel is limited to
+ ten per cent or less of the main channel's speed.
+
+ XMODEM and YMODEM are half duplex protocols which do not attempt to
+ transmit information and control signals in both directions at the same
+ time. This avoids buffer overrun problems that have been reported by
+ users attempting to exploit full duplex asynchronous file transfer
+ protocols such as Blast.
+
+ Professional-YAM adds several proprietary logic enhancements to XMODEM's
+ error detection and recovery. These compatible enhancements eliminate
+ most of the bad file transfers other programs make when using the XMODEM
+ protocol under less than ideal conditions.
+
+
+ 4.3 XMODEM-1k 1024 Byte Block
+
+ Disappointing throughput downloading from Unix with YMODEM[1] lead to the
+ development of 1024 byte blocks in 1982. 1024 byte blocks reduce the
+ effect of delays from timesharing systems, modems, and packet switched
+ networks on throughput by 87.5 per cent in addition to decreasing XMODEM's
+ 3 per cent overhead (block number, CRC, etc.).
+
+ Some environments cannot accept 1024 byte bursts, including some networks
+ and minicomputer ports. The longer block length should be an option.
+
+ The choice to use 1024 byte blocks is expressed to the sending program on
+ its command line or selection menu.[2] 1024 byte blocks improve throughput
+ in many applications.
+
+ An STX (02) replaces the SOH (01) at the beginning of the transmitted
+ block to notify the receiver of the longer block length. The transmitted
+ block contains 1024 bytes of data. The receiver should be able to accept
+ any mixture of 128 and 1024 byte blocks. The block number (in the second
+ and third bytes of the block) is incremented by one for each block
+ regardless of the block length.
+
+ The sender must not change between 128 and 1024 byte block lengths if it
+ has not received a valid ACK for the current block. Failure to observe
+
+
+ __________
+
+ 1. The name hadn't been coined yet, but the protocol was the same.
+
+ 2. See "KMD/IMP Exceptions to YMODEM" below.
+
+
+
+
+ Chapter 4 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 12
+
+
+
+ this restriction allows transmission errors to pass undetected.
+
+ If 1024 byte blocks are being used, it is possible for a file to "grow" up
+ to the next multiple of 1024 bytes. This does not waste disk space if the
+ allocation granularity is 1k or greater. With YMODEM batch transmission,
+ the optional file length transmitted in the file name block allows the
+ receiver to discard the padding, preserving the exact file length and
+ contents.
+
+ 1024 byte blocks may be used with batch file transmission or with single
+ file transmission. CRC-16 should be used with the k option to preserve
+ data integrity over phone lines. If a program wishes to enforce this
+ recommendation, it should cancel the transfer, then issue an informative
+ diagnostic message if the receiver requests checksum instead of CRC-16.
+
+ Under no circumstances may a sending program use CRC-16 unless the
+ receiver commands CRC-16.
+
+ Figure 1. XMODEM-1k Blocks
+
+ SENDER RECEIVER
+ "sx -k foo.bar"
+ "foo.bar open x.x minutes"
+ C
+ STX 01 FE Data[1024] CRC CRC
+ ACK
+ STX 02 FD Data[1024] CRC CRC
+ ACK
+ STX 03 FC Data[1000] CPMEOF[24] CRC CRC
+ ACK
+ EOT
+ ACK
+
+ Figure 2. Mixed 1024 and 128 byte Blocks
+
+ SENDER RECEIVER
+ "sx -k foo.bar"
+ "foo.bar open x.x minutes"
+ C
+ STX 01 FE Data[1024] CRC CRC
+ ACK
+ STX 02 FD Data[1024] CRC CRC
+ ACK
+ SOH 03 FC Data[128] CRC CRC
+ ACK
+ SOH 04 FB Data[100] CPMEOF[28] CRC CRC
+ ACK
+ EOT
+ ACK
+
+
+
+
+
+ Chapter 4 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 13
+
+
+
+ 5. YMODEM Batch File Transmission
+
+ The YMODEM Batch protocol is an extension to the XMODEM/CRC protocol that
+ allows 0 or more files to be transmitted with a single command. (Zero
+ files may be sent if none of the requested files is accessible.) The
+ design approach of the YMODEM Batch protocol is to use the normal routines
+ for sending and receiving XMODEM blocks in a layered fashion similar to
+ packet switching methods.
+
+ Why was it necessary to design a new batch protocol when one already
+ existed in MODEM7?[1] The batch file mode used by MODEM7 is unsuitable
+ because it does not permit full pathnames, file length, file date, or
+ other attribute information to be transmitted. Such a restrictive design,
+ hastily implemented with only CP/M in mind, would not have permitted
+ extensions to current areas of personal computing such as Unix, DOS, and
+ object oriented systems. In addition, the MODEM7 batch file mode is
+ somewhat susceptible to transmission impairments.
+
+ As in the case of single a file transfer, the receiver initiates batch
+ file transmission by sending a "C" character (for CRC-16).
+
+ The sender opens the first file and sends block number 0 with the
+ following information.[2]
+
+ Only the pathname (file name) part is required for batch transfers.
+
+ To maintain upwards compatibility, all unused bytes in block 0 must be set
+ to null.
+
+ Pathname The pathname (conventionally, the file name) is sent as a null
+ terminated ASCII string. This is the filename format used by the
+ handle oriented MSDOS(TM) functions and C library fopen functions.
+ An assembly language example follows:
+ DB 'foo.bar',0
+ No spaces are included in the pathname. Normally only the file name
+ stem (no directory prefix) is transmitted unless the sender has
+ selected YAM's f option to send the full pathname. The source drive
+ (A:, B:, etc.) is not sent.
+
+ Filename Considerations:
+
+
+
+ __________
+
+ 1. The MODEM7 batch protocol transmitted CP/M FCB bytes f1...f8 and
+ t1...t3 one character at a time. The receiver echoed these bytes as
+ received, one at a time.
+
+ 2. Only the data part of the block is described here.
+
+
+
+
+ Chapter 5 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 14
+
+
+
+ + File names are forced to lower case unless the sending system
+ supports upper/lower case file names. This is a convenience for
+ users of systems (such as Unix) which store filenames in upper
+ and lower case.
+
+ + The receiver should accommodate file names in lower and upper
+ case.
+
+ + When transmitting files between different operating systems,
+ file names must be acceptable to both the sender and receiving
+ operating systems.
+
+ If directories are included, they are delimited by /; i.e.,
+ "subdir/foo" is acceptable, "subdir\foo" is not.
+
+ Length The file length and each of the succeeding fields are optional.[3]
+ The length field is stored in the block as a decimal string counting
+ the number of data bytes in the file. The file length does not
+ include any CPMEOF (^Z) or other garbage characters used to pad the
+ last block.
+
+ If the file being transmitted is growing during transmission, the
+ length field should be set to at least the final expected file
+ length, or not sent.
+
+ The receiver stores the specified number of characters, discarding
+ any padding added by the sender to fill up the last block.
+
+ Modification Date The mod date is optional, and the filename and length
+ may be sent without requiring the mod date to be sent.
+
+ Iff the modification date is sent, a single space separates the
+ modification date from the file length.
+
+ The mod date is sent as an octal number giving the time the contents
+ of the file were last changed, measured in seconds from Jan 1 1970
+ Universal Coordinated Time (GMT). A date of 0 implies the
+ modification date is unknown and should be left as the date the file
+ is received.
+
+ This standard format was chosen to eliminate ambiguities arising from
+ transfers between different time zones.
+
+
+
+
+
+ __________
+
+ 3. Fields may not be skipped.
+
+
+
+
+ Chapter 5 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 15
+
+
+
+ Mode Iff the file mode is sent, a single space separates the file mode
+ from the modification date. The file mode is stored as an octal
+ string. Unless the file originated from a Unix system, the file mode
+ is set to 0. rb(1) checks the file mode for the 0x8000 bit which
+ indicates a Unix type regular file. Files with the 0x8000 bit set
+ are assumed to have been sent from another Unix (or similar) system
+ which uses the same file conventions. Such files are not translated
+ in any way.
+
+
+ Serial Number Iff the serial number is sent, a single space separates the
+ serial number from the file mode. The serial number of the
+ transmitting program is stored as an octal string. Programs which do
+ not have a serial number should omit this field, or set it to 0. The
+ receiver's use of this field is optional.
+
+
+ Other Fields YMODEM was designed to allow additional header fields to be
+ added as above without creating compatibility problems with older
+ YMODEM programs. Please contact Omen Technology if other fields are
+ needed for special application requirements.
+
+ The rest of the block is set to nulls. This is essential to preserve
+ upward compatibility.[4]
+
+ If the filename block is received with a CRC or other error, a
+ retransmission is requested. After the filename block has been received,
+ it is ACK'ed if the write open is successful. If the file cannot be
+ opened for writing, the receiver cancels the transfer with CAN characters
+ as described above.
+
+ The receiver then initiates transfer of the file contents with a "C"
+ character, according to the standard XMODEM/CRC protocol.
+
+ After the file contents and XMODEM EOT have been transmitted and
+ acknowledged, the receiver again asks for the next pathname.
+
+ Transmission of a null pathname terminates batch file transmission.
+
+ Note that transmission of no files is not necessarily an error. This is
+ possible if none of the files requested of the sender could be opened for
+ reading.
+
+
+
+ __________
+
+ 4. If, perchance, this information extends beyond 128 bytes (possible
+ with Unix 4.2 BSD extended file names), the block should be sent as a
+ 1k block as described above.
+
+
+
+
+ Chapter 5 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 16
+
+
+
+ Most YMODEM receivers request CRC-16 by default.
+
+ The Unix programs sz(1) and rz(1) included in the source code file
+ RZSZ.ZOO should answer other questions about YMODEM batch protocol.
+
+ Figure 3. YMODEM Batch Transmission Session (1 file)
+
+ SENDER RECEIVER
+ "sb foo.*<CR>"
+ "sending in batch mode etc."
+ C (command:rb)
+ SOH 00 FF foo.c NUL[123] CRC CRC
+ ACK
+ C
+ SOH 01 FE Data[128] CRC CRC
+ ACK
+ SOH 02 FC Data[128] CRC CRC
+ ACK
+ SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+ ACK
+ EOT
+ NAK
+ EOT
+ ACK
+ C
+ SOH 00 FF NUL[128] CRC CRC
+ ACK
+
+ Figure 7. YMODEM Header Information and Features
+
+ _____________________________________________________________
+ | Program | Length | Date | Mode | S/N | 1k-Blk | YMODEM-g |
+ |___________|________|______|______|_____|________|__________|
+ |Unix rz/sz | yes | yes | yes | no | yes | sb only |
+ |___________|________|______|______|_____|________|__________|
+ |VMS rb/sb | yes | no | no | no | yes | no |
+ |___________|________|______|______|_____|________|__________|
+ |Pro-YAM | yes | yes | no | yes | yes | yes |
+ |___________|________|______|______|_____|________|__________|
+ |CP/M YAM | no | no | no | no | yes | no |
+ |___________|________|______|______|_____|________|__________|
+ |KMD/IMP | ? | no | no | no | yes | no |
+ |___________|________|______|______|_____|________|__________|
+
+ 5.1 KMD/IMP Exceptions to YMODEM
+
+ KMD and IMP use a "CK" character sequence emitted by the receiver to
+ trigger the use of 1024 byte blocks as an alternative to specifying this
+ option to the sending program. This two character sequence generally
+ works well on single process micros in direct communication, provided the
+ programs rigorously adhere to all the XMODEM recommendations included
+
+
+
+ Chapter 5 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 17
+
+
+
+ Figure 4. YMODEM Batch Transmission Session (2 files)
+
+ SENDER RECEIVER
+ "sb foo.c baz.c<CR>"
+ "sending in batch mode etc."
+ C (command:rb)
+ SOH 00 FF foo.c NUL[123] CRC CRC
+ ACK
+ C
+ SOH 01 FE Data[128] CRC CRC
+ ACK
+ SOH 02 FC Data[128] CRC CRC
+ ACK
+ SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+ ACK
+ EOT
+ NAK
+ EOT
+ ACK
+ C
+ SOH 00 FF baz.c NUL[123] CRC CRC
+ ACK
+ C
+ SOH 01 FB Data[100] CPMEOF[28] CRC CRC
+ ACK
+ EOT
+ NAK
+ EOT
+ ACK
+ C
+ SOH 00 FF NUL[128] CRC CRC
+ ACK
+
+ Figure 5. YMODEM Batch Transmission Session-1k Blocks
+
+ SENDER RECEIVER
+ "sb -k foo.*<CR>"
+ "sending in batch mode etc."
+ C (command:rb)
+ SOH 00 FF foo.c NUL[123] CRC CRC
+ ACK
+ C
+ STX 01 FD Data[1024] CRC CRC
+ ACK
+ SOH 02 FC Data[128] CRC CRC
+ ACK
+ SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+ ACK
+ EOT
+ NAK
+ EOT
+
+
+
+ Chapter 5 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 18
+
+
+
+ ACK
+ C
+ SOH 00 FF NUL[128] CRC CRC
+ ACK
+
+ Figure 6. YMODEM Filename block transmitted by sz
+
+ -rw-r--r-- 6347 Jun 17 1984 20:34 bbcsched.txt
+
+ 00 0100FF62 62637363 6865642E 74787400 |...bbcsched.txt.|
+ 10 36333437 20333331 34373432 35313320 |6347 3314742513 |
+ 20 31303036 34340000 00000000 00000000 |100644..........|
+ 30 00000000 00000000 00000000 00000000
+ 40 00000000 00000000 00000000 00000000
+ 50 00000000 00000000 00000000 00000000
+ 60 00000000 00000000 00000000 00000000
+ 70 00000000 00000000 00000000 00000000
+ 80 000000CA 56
+
+ herein. Programs with marginal XMODEM implementations do not fare so
+ well. Timesharing systems and packet switched networks can separate the
+ successive characters, rendering this method unreliable.
+
+ Sending programs may detect the CK sequence if the operating enviornment
+ does not preclude reliable implementation.
+
+ Instead of the standard YMODEM file length in decimal, KMD and IMP
+ transmit the CP/M record count in the last two bytes of the header block.
+
+
+ 6. YMODEM-g File Transmission
+
+ Developing technology is providing phone line data transmission at ever
+ higher speeds using very specialized techniques. These high speed modems,
+ as well as session protocols such as X.PC, provide high speed, nearly
+ error free communications at the expense of considerably increased delay
+ time.
+
+ This delay time is moderate compared to human interactions, but it
+ cripples the throughput of most error correcting protocols.
+
+ The g option to YMODEM has proven effective under these circumstances.
+ The g option is driven by the receiver, which initiates the batch transfer
+ by transmitting a G instead of C. When the sender recognizes the G, it
+ bypasses the usual wait for an ACK to each transmitted block, sending
+ succeeding blocks at full speed, subject to XOFF/XON or other flow control
+ exerted by the medium.
+
+ The sender expects an inital G to initiate the transmission of a
+ particular file, and also expects an ACK on the EOT sent at the end of
+ each file. This synchronization allows the receiver time to open and
+
+
+
+ Chapter 6 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 19
+
+
+
+ close files as necessary.
+
+ If an error is detected in a YMODEM-g transfer, the receiver aborts the
+ transfer with the multiple CAN abort sequence. The ZMODEM protocol should
+ be used in applications that require both streaming throughput and error
+ recovery.
+
+ Figure 8. YMODEM-g Transmission Session
+
+ SENDER RECEIVER
+ "sb foo.*<CR>"
+ "sending in batch mode etc..."
+ G (command:rb -g)
+ SOH 00 FF foo.c NUL[123] CRC CRC
+ G
+ SOH 01 FE Data[128] CRC CRC
+ STX 02 FD Data[1024] CRC CRC
+ SOH 03 FC Data[128] CRC CRC
+ SOH 04 FB Data[100] CPMEOF[28] CRC CRC
+ EOT
+ ACK
+ G
+ SOH 00 FF NUL[128] CRC CRC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 6 XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 20
+
+
+
+ 7. XMODEM PROTOCOL OVERVIEW
+
+ 8/9/82 by Ward Christensen.
+
+ I will maintain a master copy of this. Please pass on changes or
+ suggestions via CBBS/Chicago at (312) 545-8086, CBBS/CPMUG (312) 849-1132
+ or by voice at (312) 849-6279.
+
+ 7.1 Definitions
+
+ <soh> 01H
+ <eot> 04H
+ <ack> 06H
+ <nak> 15H
+ <can> 18H
+ <C> 43H
+
+
+ 7.2 Transmission Medium Level Protocol
+
+ Asynchronous, 8 data bits, no parity, one stop bit.
+
+ The protocol imposes no restrictions on the contents of the data being
+ transmitted. No control characters are looked for in the 128-byte data
+ messages. Absolutely any kind of data may be sent - binary, ASCII, etc.
+ The protocol has not formally been adopted to a 7-bit environment for the
+ transmission of ASCII-only (or unpacked-hex) data , although it could be
+ simply by having both ends agree to AND the protocol-dependent data with
+ 7F hex before validating it. I specifically am referring to the checksum,
+ and the block numbers and their ones- complement.
+
+ Those wishing to maintain compatibility of the CP/M file structure, i.e.
+ to allow modemming ASCII files to or from CP/M systems should follow this
+ data format:
+
+ + ASCII tabs used (09H); tabs set every 8.
+
+ + Lines terminated by CR/LF (0DH 0AH)
+
+ + End-of-file indicated by ^Z, 1AH. (one or more)
+
+ + Data is variable length, i.e. should be considered a continuous
+ stream of data bytes, broken into 128-byte chunks purely for the
+ purpose of transmission.
+
+ + A CP/M "peculiarity": If the data ends exactly on a 128-byte
+ boundary, i.e. CR in 127, and LF in 128, a subsequent sector
+ containing the ^Z EOF character(s) is optional, but is preferred.
+ Some utilities or user programs still do not handle EOF without ^Zs.
+
+
+
+
+
+ Chapter 7 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 21
+
+
+
+ + The last block sent is no different from others, i.e. there is no
+ "short block".
+ Figure 9. XMODEM Message Block Level Protocol
+
+ Each block of the transfer looks like:
+ <SOH><blk #><255-blk #><--128 data bytes--><cksum>
+ in which:
+ <SOH> = 01 hex
+ <blk #> = binary number, starts at 01 increments by 1, and
+ wraps 0FFH to 00H (not to 01)
+ <255-blk #> = blk # after going thru 8080 "CMA" instr, i.e.
+ each bit complemented in the 8-bit block number.
+ Formally, this is the "ones complement".
+ <cksum> = the sum of the data bytes only. Toss any carry.
+
+ 7.3 File Level Protocol
+
+ 7.3.1 Common_to_Both_Sender_and_Receiver
+ All errors are retried 10 times. For versions running with an operator
+ (i.e. NOT with XMODEM), a message is typed after 10 errors asking the
+ operator whether to "retry or quit".
+
+ Some versions of the protocol use <can>, ASCII ^X, to cancel transmission.
+ This was never adopted as a standard, as having a single "abort" character
+ makes the transmission susceptible to false termination due to an <ack>
+ <nak> or <soh> being corrupted into a <can> and aborting transmission.
+
+ The protocol may be considered "receiver driven", that is, the sender need
+ not automatically re-transmit, although it does in the current
+ implementations.
+
+
+ 7.3.2 Receive_Program_Considerations
+ The receiver has a 10-second timeout. It sends a <nak> every time it
+ times out. The receiver's first timeout, which sends a <nak>, signals the
+ transmitter to start. Optionally, the receiver could send a <nak>
+ immediately, in case the sender was ready. This would save the initial 10
+ second timeout. However, the receiver MUST continue to timeout every 10
+ seconds in case the sender wasn't ready.
+
+ Once into a receiving a block, the receiver goes into a one-second timeout
+ for each character and the checksum. If the receiver wishes to <nak> a
+ block for any reason (invalid header, timeout receiving data), it must
+ wait for the line to clear. See "programming tips" for ideas
+
+ Synchronizing: If a valid block number is received, it will be: 1) the
+ expected one, in which case everything is fine; or 2) a repeat of the
+ previously received block. This should be considered OK, and only
+ indicates that the receivers <ack> got glitched, and the sender re-
+ transmitted; 3) any other block number indicates a fatal loss of
+ synchronization, such as the rare case of the sender getting a line-glitch
+
+
+
+ Chapter 7 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 22
+
+
+
+ that looked like an <ack>. Abort the transmission, sending a <can>
+
+
+ 7.3.3 Sending_program_considerations
+ While waiting for transmission to begin, the sender has only a single very
+ long timeout, say one minute. In the current protocol, the sender has a
+ 10 second timeout before retrying. I suggest NOT doing this, and letting
+ the protocol be completely receiver-driven. This will be compatible with
+ existing programs.
+
+ When the sender has no more data, it sends an <eot>, and awaits an <ack>,
+ resending the <eot> if it doesn't get one. Again, the protocol could be
+ receiver-driven, with the sender only having the high-level 1-minute
+ timeout to abort.
+
+
+ Here is a sample of the data flow, sending a 3-block message. It includes
+ the two most common line hits - a garbaged block, and an <ack> reply
+ getting garbaged. <xx> represents the checksum byte.
+
+ Figure 10. Data flow including Error Recovery
+
+ SENDER RECEIVER
+ times out after 10 seconds,
+ <--- <nak>
+ <soh> 01 FE -data- <xx> --->
+ <--- <ack>
+ <soh> 02 FD -data- xx ---> (data gets line hit)
+ <--- <nak>
+ <soh> 02 FD -data- xx --->
+ <--- <ack>
+ <soh> 03 FC -data- xx --->
+ (ack gets garbaged) <--- <ack>
+ <soh> 03 FC -data- xx ---> <ack>
+ <eot> --->
+ <--- <anything except ack>
+ <eot> --->
+ <--- <ack>
+ (finished)
+
+ 7.4 Programming Tips
+
+ + The character-receive subroutine should be called with a parameter
+ specifying the number of seconds to wait. The receiver should first
+ call it with a time of 10, then <nak> and try again, 10 times.
+
+ After receiving the <soh>, the receiver should call the character
+ receive subroutine with a 1-second timeout, for the remainder of the
+ message and the <cksum>. Since they are sent as a continuous stream,
+ timing out of this implies a serious like glitch that caused, say,
+ 127 characters to be seen instead of 128.
+
+
+
+ Chapter 7 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 23
+
+
+
+ + When the receiver wishes to <nak>, it should call a "PURGE"
+ subroutine, to wait for the line to clear. Recall the sender tosses
+ any characters in its UART buffer immediately upon completing sending
+ a block, to ensure no glitches were mis- interpreted.
+
+ The most common technique is for "PURGE" to call the character
+ receive subroutine, specifying a 1-second timeout,[1] and looping
+ back to PURGE until a timeout occurs. The <nak> is then sent,
+ ensuring the other end will see it.
+
+ + You may wish to add code recommended by John Mahr to your character
+ receive routine - to set an error flag if the UART shows framing
+ error, or overrun. This will help catch a few more glitches - the
+ most common of which is a hit in the high bits of the byte in two
+ consecutive bytes. The <cksum> comes out OK since counting in 1-byte
+ produces the same result of adding 80H + 80H as with adding 00H +
+ 00H.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __________
+
+ 1. These times should be adjusted for use with timesharing systems.
+
+
+
+
+ Chapter 7 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 24
+
+
+
+ 8. XMODEM/CRC Overview
+
+ Original 1/13/85 by John Byrns -- CRC option.
+
+ Please pass on any reports of errors in this document or suggestions for
+ improvement to me via Ward's/CBBS at (312) 849-1132, or by voice at (312)
+ 885-1105.
+
+ The CRC used in the Modem Protocol is an alternate form of block check
+ which provides more robust error detection than the original checksum.
+ Andrew S. Tanenbaum says in his book, Computer Networks, that the CRC-
+ CCITT used by the Modem Protocol will detect all single and double bit
+ errors, all errors with an odd number of bits, all burst errors of length
+ 16 or less, 99.997% of 17-bit error bursts, and 99.998% of 18-bit and
+ longer bursts.[1]
+
+ The changes to the Modem Protocol to replace the checksum with the CRC are
+ straight forward. If that were all that we did we would not be able to
+ communicate between a program using the old checksum protocol and one
+ using the new CRC protocol. An initial handshake was added to solve this
+ problem. The handshake allows a receiving program with CRC capability to
+ determine whether the sending program supports the CRC option, and to
+ switch it to CRC mode if it does. This handshake is designed so that it
+ will work properly with programs which implement only the original
+ protocol. A description of this handshake is presented in section 10.
+
+ Figure 11. Message Block Level Protocol, CRC mode
+
+ Each block of the transfer in CRC mode looks like:
+ <SOH><blk #><255-blk #><--128 data bytes--><CRC hi><CRC lo>
+ in which:
+ <SOH> = 01 hex
+ <blk #> = binary number, starts at 01 increments by 1, and
+ wraps 0FFH to 00H (not to 01)
+ <255-blk #> = ones complement of blk #.
+ <CRC hi> = byte containing the 8 hi order coefficients of the CRC.
+ <CRC lo> = byte containing the 8 lo order coefficients of the CRC.
+
+ 8.1 CRC Calculation
+
+ 8.1.1 Formal_Definition
+ To calculate the 16 bit CRC the message bits are considered to be the
+ coefficients of a polynomial. This message polynomial is first multiplied
+ by X^16 and then divided by the generator polynomial (X^16 + X^12 + X^5 +
+
+
+ __________
+
+ 1. This reliability figure is misleading because XMODEM's critical
+ supervisory functions are not protected by this CRC.
+
+
+
+
+ Chapter 8 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 25
+
+
+
+ 1) using modulo two arithmetic. The remainder left after the division is
+ the desired CRC. Since a message block in the Modem Protocol is 128 bytes
+ or 1024 bits, the message polynomial will be of order X^1023. The hi order
+ bit of the first byte of the message block is the coefficient of X^1023 in
+ the message polynomial. The lo order bit of the last byte of the message
+ block is the coefficient of X^0 in the message polynomial.
+
+ Figure 12. Example of CRC Calculation written in C
+
+ The following XMODEM crc routine is taken from "rbsb.c". Please refer to
+ the source code for these programs (contained in RZSZ.ZOO) for usage. A
+ fast table driven version is also included in this file.
+
+ /* update CRC */
+ unsigned short
+ updcrc(c, crc)
+ register c;
+ register unsigned crc;
+ {
+ register count;
+
+ for (count=8; --count>=0;) {
+ if (crc & 0x8000) {
+ crc <<= 1;
+ crc += (((c<<=1) & 0400) != 0);
+ crc ^= 0x1021;
+ }
+ else {
+ crc <<= 1;
+ crc += (((c<<=1) & 0400) != 0);
+ }
+ }
+ return crc;
+ }
+
+ 8.2 CRC File Level Protocol Changes
+
+ 8.2.1 Common_to_Both_Sender_and_Receiver
+ The only change to the File Level Protocol for the CRC option is the
+ initial handshake which is used to determine if both the sending and the
+ receiving programs support the CRC mode. All Modem Programs should support
+ the checksum mode for compatibility with older versions. A receiving
+ program that wishes to receive in CRC mode implements the mode setting
+ handshake by sending a <C> in place of the initial <nak>. If the sending
+ program supports CRC mode it will recognize the <C> and will set itself
+ into CRC mode, and respond by sending the first block as if a <nak> had
+ been received. If the sending program does not support CRC mode it will
+ not respond to the <C> at all. After the receiver has sent the <C> it will
+ wait up to 3 seconds for the <soh> that starts the first block. If it
+ receives a <soh> within 3 seconds it will assume the sender supports CRC
+ mode and will proceed with the file exchange in CRC mode. If no <soh> is
+
+
+
+ Chapter 8 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 26
+
+
+
+ received within 3 seconds the receiver will switch to checksum mode, send
+ a <nak>, and proceed in checksum mode. If the receiver wishes to use
+ checksum mode it should send an initial <nak> and the sending program
+ should respond to the <nak> as defined in the original Modem Protocol.
+ After the mode has been set by the initial <C> or <nak> the protocol
+ follows the original Modem Protocol and is identical whether the checksum
+ or CRC is being used.
+
+
+ 8.2.2 Receive_Program_Considerations
+ There are at least 4 things that can go wrong with the mode setting
+ handshake.
+
+ 1. the initial <C> can be garbled or lost.
+
+ 2. the initial <soh> can be garbled.
+
+ 3. the initial <C> can be changed to a <nak>.
+
+ 4. the initial <nak> from a receiver which wants to receive in checksum
+ can be changed to a <C>.
+
+ The first problem can be solved if the receiver sends a second <C> after
+ it times out the first time. This process can be repeated several times.
+ It must not be repeated too many times before sending a <nak> and
+ switching to checksum mode or a sending program without CRC support may
+ time out and abort. Repeating the <C> will also fix the second problem if
+ the sending program cooperates by responding as if a <nak> were received
+ instead of ignoring the extra <C>.
+
+ It is possible to fix problems 3 and 4 but probably not worth the trouble
+ since they will occur very infrequently. They could be fixed by switching
+ modes in either the sending or the receiving program after a large number
+ of successive <nak>s. This solution would risk other problems however.
+
+
+ 8.2.3 Sending_Program_Considerations
+ The sending program should start in the checksum mode. This will insure
+ compatibility with checksum only receiving programs. Anytime a <C> is
+ received before the first <nak> or <ack> the sending program should set
+ itself into CRC mode and respond as if a <nak> were received. The sender
+ should respond to additional <C>s as if they were <nak>s until the first
+ <ack> is received. This will assist the receiving program in determining
+ the correct mode when the <soh> is lost or garbled. After the first <ack>
+ is received the sending program should ignore <C>s.
+
+
+
+
+
+
+
+
+
+ Chapter 8 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 27
+
+
+
+ 8.3 Data Flow Examples with CRC Option
+
+ Here is a data flow example for the case where the receiver requests
+ transmission in the CRC mode but the sender does not support the CRC
+ option. This example also includes various transmission errors. <xx>
+ represents the checksum byte.
+
+ Figure 13. Data Flow: Receiver has CRC Option, Sender Doesn't
+
+ SENDER RECEIVER
+ <--- <C>
+ times out after 3 seconds,
+ <--- <C>
+ times out after 3 seconds,
+ <--- <C>
+ times out after 3 seconds,
+ <--- <C>
+ times out after 3 seconds,
+ <--- <nak>
+ <soh> 01 FE -data- <xx> --->
+ <--- <ack>
+ <soh> 02 FD -data- <xx> ---> (data gets line hit)
+ <--- <nak>
+ <soh> 02 FD -data- <xx> --->
+ <--- <ack>
+ <soh> 03 FC -data- <xx> --->
+ (ack gets garbaged) <--- <ack>
+ times out after 10 seconds,
+ <--- <nak>
+ <soh> 03 FC -data- <xx> --->
+ <--- <ack>
+ <eot> --->
+ <--- <ack>
+
+ Here is a data flow example for the case where the receiver requests
+ transmission in the CRC mode and the sender supports the CRC option. This
+ example also includes various transmission errors. <xxxx> represents the
+ 2 CRC bytes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 8 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 28
+
+
+
+ Figure 14. Receiver and Sender Both have CRC Option
+
+ SENDER RECEIVER
+ <--- <C>
+ <soh> 01 FE -data- <xxxx> --->
+ <--- <ack>
+ <soh> 02 FD -data- <xxxx> ---> (data gets line hit)
+ <--- <nak>
+ <soh> 02 FD -data- <xxxx> --->
+ <--- <ack>
+ <soh> 03 FC -data- <xxxx> --->
+ (ack gets garbaged) <--- <ack>
+ times out after 10 seconds,
+ <--- <nak>
+ <soh> 03 FC -data- <xxxx> --->
+ <--- <ack>
+ <eot> --->
+ <--- <ack>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 8 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 29
+
+
+
+ 9. MORE INFORMATION
+
+ Please contact Omen Technology for troff source files and typeset copies
+ of this document.
+
+
+ 9.1 TeleGodzilla Bulletin Board
+
+ More information may be obtained by calling TeleGodzilla at 503-621-3746.
+ Speed detection is automatic for 1200, 2400 and 19200(Telebit PEP) bps.
+ TrailBlazer modem users may issue the TeleGodzilla trailblazer command to
+ swith to 19200 bps once they have logged in.
+
+ Interesting files include RZSZ.ZOO (C source code), YZMODEM.ZOO (Official
+ XMODEM, YMODEM, and ZMODEM protocol descriptions), ZCOMMEXE.ARC,
+ ZCOMMDOC.ARC, and ZCOMMHLP.ARC (PC-DOS shareware comm program with XMODEM,
+ True YMODEM(TM), ZMODEM, Kermit Sliding Windows, Telink, MODEM7 Batch,
+ script language, etc.).
+
+
+ 9.2 Unix UUCP Access
+
+ UUCP sites can obtain the current version of this file with
+ uucp omen!/u/caf/public/ymodem.doc /tmp
+ A continually updated list of available files is stored in
+ /usr/spool/uucppublic/FILES. When retrieving these files with uucp,
+ remember that the destination directory on your system must be writeable
+ by anyone, or the UUCP transfer will fail.
+
+ The following L.sys line calls TeleGodzilla (Pro-YAM in host operation).
+ TeleGodzilla determines the incoming speed automatically.
+
+ In response to "Name Please:" uucico gives the Pro-YAM "link" command as a
+ user name. The password (Giznoid) controls access to the Xenix system
+ connected to the IBM PC's other serial port. Communications between
+ Pro-YAM and Xenix use 9600 bps; YAM converts this to the caller's speed.
+
+ Finally, the calling uucico logs in as uucp.
+
+ omen Any ACU 2400 1-503-621-3746 se:--se: link ord: Giznoid in:--in: uucp
+
+
+
+ 10. REVISIONS
+
+ 6-18-88 Further revised for clarity. Corrected block numbering in two
+ examples.
+ 10-27-87 Optional fields added for number of files remaining to be sent
+ and total number of bytes remaining to be sent.
+ 10-18-87 Flow control discussion added to 1024 byte block descritpion,
+ minor revisions for clarity per user comments.
+
+
+
+ Chapter 10 Xmodem Protocol Overview
+
+
+
+
+
+
+
+ X/YMODEM Protocol Reference June 18 1988 30
+
+
+
+ 8-03-87 Revised for clarity.
+ 5-31-1987 emphasizes minimum requirements for YMODEM, and updates
+ information on accessing files.
+ 9-11-1986 clarifies nomenclature and some minor points.
+ The April 15 1986 edition clarifies some points concerning CRC
+ calculations and spaces in the header.
+
+
+ 11. YMODEM Programs
+
+ ZCOMM, A shareware little brother to Professional-YAM, is available as
+ ZCOMMEXE.ARC on TeleGodzilla and other bulletin board systems. ZCOMM may
+ be used to test YMODEM amd ZMODEM implementations.
+
+ Unix programs supporting YMODEM are available on TeleGodzilla in RZSZ.ZOO.
+ This ZOO archive includes a ZCOMM/Pro-YAM/PowerCom script ZUPL.T to upload
+ a bootstrap program MINIRB.C, compile it, and then upload the rest of the
+ files using the compiled MINIRB. Most Unix like systems are supported,
+ including V7, Xenix, Sys III, 4.2 BSD, SYS V, Idris, Coherent, and
+ Regulus.
+
+ A version for VAX-VMS is available in VRBSB.SHQ.
+
+ Irv Hoff has added 1k blocks and basic YMODEM batch transfers to the KMD
+ and IMP series programs, which replace the XMODEM and MODEM7/MDM7xx series
+ respectively. Overlays are available for a wide variety of CP/M systems.
+
+ Questions about Professional-YAM communications software may be directed
+ to:
+ Chuck Forsberg
+ Omen Technology Inc
+ 17505-V Sauvie Island Road
+ Portland Oregon 97231
+ VOICE: 503-621-3406 :VOICE
+ Modem: 503-621-3746 Speed: 19200(Telebit PEP),2400,1200,300
+ Usenet: ...!tektronix!reed!omen!caf
+ CompuServe: 70007,2304
+ GEnie: CAF
+
+ Unlike ZMODEM and Kermit, XMODEM and YMODEM place obstacles in the path of
+ a reliable high performance implementation, evidenced by poor reliability
+ under stress of the industry leaders' XMODEM and YMODEM programs. Omen
+ Technology provides consulting and other services to those wishing to
+ implement XMODEM, YMODEM, and ZMODEM with state of the art features and
+ reliability.
+
+
+
+
+
+
+
+
+
+ Chapter 11 Xmodem Protocol Overview
+
+
+
+
+
+
+
+
+
+
+
+ CONTENTS
+
+
+ 1. TOWER OF BABEL................................................... 2
+ 1.1 Definitions................................................. 2
+
+ 2. YMODEM MINIMUM REQUIREMENTS...................................... 4
+
+ 3. WHY YMODEM?...................................................... 6
+ 3.1 Some Messages from the Pioneer.............................. 7
+
+ 4. XMODEM PROTOCOL ENHANCEMENTS..................................... 10
+ 4.1 Graceful Abort.............................................. 10
+ 4.2 CRC-16 Option............................................... 10
+ 4.3 XMODEM-1k 1024 Byte Block................................... 11
+
+ 5. YMODEM Batch File Transmission................................... 13
+ 5.1 KMD/IMP Exceptions to YMODEM................................ 16
+
+ 6. YMODEM-g File Transmission....................................... 18
+
+ 7. XMODEM PROTOCOL OVERVIEW......................................... 20
+ 7.1 Definitions................................................. 20
+ 7.2 Transmission Medium Level Protocol.......................... 20
+ 7.3 File Level Protocol......................................... 21
+ 7.4 Programming Tips............................................ 22
+
+ 8. XMODEM/CRC Overview.............................................. 24
+ 8.1 CRC Calculation............................................. 24
+ 8.2 CRC File Level Protocol Changes............................. 25
+ 8.3 Data Flow Examples with CRC Option.......................... 27
+
+ 9. MORE INFORMATION................................................. 29
+ 9.1 TeleGodzilla Bulletin Board................................. 29
+ 9.2 Unix UUCP Access............................................ 29
+
+ 10. REVISIONS........................................................ 29
+
+ 11. YMODEM Programs.................................................. 30
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - i -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LIST OF FIGURES
+
+
+ Figure 1. XMODEM-1k Blocks.......................................... 12
+
+ Figure 2. Mixed 1024 and 128 byte Blocks............................ 12
+
+ Figure 3. YMODEM Batch Transmission Session (1 file)................ 16
+
+ Figure 4. YMODEM Batch Transmission Session (2 files)............... 16
+
+ Figure 5. YMODEM Batch Transmission Session-1k Blocks............... 16
+
+ Figure 6. YMODEM Filename block transmitted by sz................... 16
+
+ Figure 7. YMODEM Header Information and Features.................... 16
+
+ Figure 8. YMODEM-g Transmission Session............................. 19
+
+ Figure 9. XMODEM Message Block Level Protocol....................... 21
+
+ Figure 10. Data flow including Error Recovery........................ 22
+
+ Figure 11. Message Block Level Protocol, CRC mode.................... 24
+
+ Figure 12. Example of CRC Calculation written in C................... 25
+
+ Figure 13. Data Flow: Receiver has CRC Option, Sender Doesn't........ 27
+
+ Figure 14. Receiver and Sender Both have CRC Option.................. 28
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - ii -
diff --git a/com32/sysdump/zout.c b/com32/sysdump/zout.c
new file mode 100644
index 00000000..ece934cc
--- /dev/null
+++ b/com32/sysdump/zout.c
@@ -0,0 +1,99 @@
+/*
+ * Compress input and feed it to a block-oriented back end.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "backend.h"
+#include "ctime.h"
+
+#define ALLOC_CHUNK 65536
+
+int init_data(struct backend *be, const char *argv[])
+{
+ be->now = posix_time();
+ be->argv = argv;
+
+ memset(&be->zstream, 0, sizeof be->zstream);
+
+ be->zstream.next_out = NULL;
+ be->outbuf = NULL;
+ be->zstream.avail_out = be->alloc = 0;
+ be->dbytes = be->zbytes = 0;
+
+ /* Initialize a gzip data stream */
+ if (deflateInit2(&be->zstream, 9, Z_DEFLATED,
+ 16+15, 9, Z_DEFAULT_STRATEGY) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int do_deflate(struct backend *be, int flush)
+{
+ int rv;
+ char *buf;
+
+ while (1) {
+ rv = deflate(&be->zstream, flush);
+ be->zbytes = be->alloc - be->zstream.avail_out;
+ if (be->zstream.avail_out)
+ return rv; /* Not an issue of output space... */
+
+ buf = realloc(be->outbuf, be->alloc + ALLOC_CHUNK);
+ if (!buf)
+ return Z_MEM_ERROR;
+ be->outbuf = buf;
+ be->alloc += ALLOC_CHUNK;
+ be->zstream.next_out = (void *)(buf + be->zbytes);
+ be->zstream.avail_out = be->alloc - be->zbytes;
+ }
+}
+
+
+int write_data(struct backend *be, const void *buf, size_t len)
+{
+ int rv = Z_OK;
+
+ be->zstream.next_in = (void *)buf;
+ be->zstream.avail_in = len;
+
+ be->dbytes += len;
+
+ while (be->zstream.avail_in) {
+ rv = do_deflate(be, Z_NO_FLUSH);
+ if (rv < 0) {
+ printf("do_deflate returned %d\n", rv);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* Output the data and shut down the stream */
+int flush_data(struct backend *be)
+{
+ int rv = Z_OK;
+
+ while (rv != Z_STREAM_END) {
+ rv = do_deflate(be, Z_FINISH);
+ if (rv < 0)
+ return -1;
+ }
+
+ printf("Uploading data, %u bytes... ", be->zbytes);
+
+ if (be->write(be))
+ return -1;
+
+ free(be->outbuf);
+ be->outbuf = NULL;
+ be->dbytes = be->zbytes = be->alloc = 0;
+
+ printf("done.\n");
+ return 0;
+}
diff --git a/core/bootsect.inc b/core/bootsect.inc
index 200f00ad..0cf0c460 100644
--- a/core/bootsect.inc
+++ b/core/bootsect.inc
@@ -120,6 +120,12 @@ replace_bootstrap:
; Prepare for shutting down
;
call vgaclearmode
+
+;
+; We jump here when loading a kernel image, so that we don't reset
+; the screen mode in "quiet" mode
+;
+replace_bootstrap_noclearmode:
call cleanup_hardware
;
diff --git a/core/com32.inc b/core/com32.inc
index 72327929..8c3f181a 100644
--- a/core/com32.inc
+++ b/core/com32.inc
@@ -65,6 +65,10 @@ is_com32_image:
sub cx,si
fs rep movsb
+ mov si,KernelCName
+ mov di,Com32Name
+ call strcpy
+
call comboot_setup_api ; Set up the COMBOOT-style API
mov edi,pm_entry ; Load address
@@ -172,6 +176,7 @@ com32_call_start:
; Now everything is set up for interrupts...
+ push dword Com32Name ; Module filename
push dword [HighMemSize] ; Memory managed by Syslinux
push dword com32_cfarcall ; Cfarcall entry point
push dword com32_farcall ; Farcall entry point
@@ -179,7 +184,7 @@ com32_call_start:
push dword (xfer_buf_seg << 4) ; Bounce buffer address
push dword com32_intcall ; Intcall entry point
push dword command_line ; Command line pointer
- push dword 7 ; Argument count
+ push dword 8 ; Argument count
sti ; Interrupts OK now
call pm_entry ; Run the program...
; ... on return, fall through to com32_exit ...
@@ -425,4 +430,11 @@ RealModeEAX resd 1 ; Real mode EAX
PMESP resd 1 ; Protected-mode ESP
Com32SysSP resw 1 ; SP saved during COM32 syscall
+ section .uibss
+%if IS_SYSLINUX
+Com32Name resb FILENAME_MAX+2
+%else
+Com32Name resb FILENAME_MAX
+%endif
+
section .text
diff --git a/core/comboot.inc b/core/comboot.inc
index cdba16d5..f8a78531 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -449,9 +449,9 @@ comapi_get_version:
mov P_ES,ds
; ES:SI -> version banner
- mov P_SI,syslinux_banner
+ mov P_SI,syslinux_banner + 2 ; Skip leading CR LF
; ES:DI -> copyright string
- mov P_DI,copyright_str
+ mov P_DI,copyright_str + 1 ; Skip leading space
comapi_nop:
clc
@@ -507,6 +507,7 @@ comapi_textmode:
; INT 22h AX=0006h Open file
;
comapi_open:
+ call reset_idle
push ds
mov ds,P_ES
mov si,P_SI
@@ -525,6 +526,7 @@ comapi_open:
; INT 22h AX=0007h Read file
;
comapi_read:
+ call reset_idle
mov es,P_ES
mov bx,P_BX
mov si,P_SI
@@ -577,6 +579,8 @@ comapi_derinfo:
mov P_SI,ax
mov ax,[InitStack+2]
mov P_FS,ax
+ mov eax,[MyIP]
+ mov P_ECX,eax
%else
; Physical medium...
@@ -827,6 +831,7 @@ comapi_userfont:
;
%if IS_SYSLINUX || IS_ISOLINUX || IS_EXTLINUX
comapi_readdisk:
+ call reset_idle
mov esi,P_ESI ; Enforce ESI == EDI == 0, these
or esi,P_EDI ; are reserved for future expansion
jnz .err
@@ -894,6 +899,7 @@ comapi_getcwd:
;
%if IS_SYSLINUX
comapi_opendir:
+ call reset_idle
push ds
mov ds,P_ES
mov si,P_SI
@@ -920,6 +926,7 @@ comapi_opendir equ comapi_err
;
%if IS_SYSLINUX
comapi_readdir:
+ call reset_idle
mov es,P_ES
mov di,P_DI
mov si,P_SI
diff --git a/core/configinit.inc b/core/configinit.inc
index cf6a814c..c6fdaf76 100644
--- a/core/configinit.inc
+++ b/core/configinit.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
;;
;; 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
@@ -37,11 +38,6 @@ reset_config:
%endif
%endif
- mov si,linuxauto_cmd ; Default command: "linux auto"
- mov di,default_cmd
- mov cx,linuxauto_len
- rep movsb
-
mov di,KbdMap ; Default keymap 1:1
xor al,al
inc ch ; CX <- 256
@@ -53,7 +49,3 @@ mkkeymap: stosb
mov [VKernelEnd],eax
ret
-
- section .data
-linuxauto_cmd db 'linux auto',0
-linuxauto_len equ $-linuxauto_cmd
diff --git a/core/conio.inc b/core/conio.inc
index 16c39c65..701fcf05 100644
--- a/core/conio.inc
+++ b/core/conio.inc
@@ -286,7 +286,6 @@ write_serial_str:
; pollchar: check if we have an input character pending (ZF = 0)
;
pollchar:
- call do_idle
pushad
mov ah,11h ; Poll keyboard
int 16h
diff --git a/core/cpuinit.inc b/core/cpuinit.inc
index 4d8cc2e7..4332fbc1 100644
--- a/core/cpuinit.inc
+++ b/core/cpuinit.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 2010 Intel Corporation; author: H. Peter Anvin
;;
;; 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
@@ -39,6 +40,52 @@ dosram_k equ (real_mode_seg+0x1000) >> 6 ; Minimum DOS memory (K)
enough_ram:
skip_checks:
+;
+; Detect old versions Xen HVM and disable halt
+; Xen HVM older than version 3.3 might be using vmxassist, which breaks
+; if HLT is executed in real mode.
+;
+; Note: in Syslinux 4, we should probably just execute the HLT in
+; protected mode instead.
+;
+check_xen:
+ pushfd
+ pushfd
+ pop eax
+ mov edx,eax
+ xor eax,(1 << 21) ; ID flag
+ push eax
+ popfd
+ pushfd
+ pop eax
+ popfd
+ xor eax,edx
+ and eax,(1 << 21)
+ jz .not_xen ; No CPUID
+
+ xor ebx,ebx
+ xor ecx,ecx
+ xor edx,edx
+ mov eax,0x40000000
+ cpuid
+ cmp ebx,"XenV"
+ jne .not_xen
+ cmp ecx,"MMXe"
+ jne .not_xen
+ cmp edx,"nVMM"
+ jne .not_xen
+
+ ; We're on Xen...
+ mov eax,0x40000001
+ cpuid
+ cmp eax,0x00030003
+ jae .not_xen ; Xen >= 3.3, not affected
+
+ ; We may be using vmxassist, so disable HLT
+ mov byte [ForceNoHalt],1
+
+.not_xen:
+
section .data
err_noram db 'It appears your computer has less than '
asciidec dosram_k
diff --git a/core/diskstart.inc b/core/diskstart.inc
index 53229223..b8ab790c 100644
--- a/core/diskstart.inc
+++ b/core/diskstart.inc
@@ -28,7 +28,7 @@ SuperInfo resq 16 ; The first 16 bytes expanded 8 times
; "close" to the initial stack pointer offset, in order to
; reduce the code size...
;
-StackBuf equ $-44-32 ; Start the stack here (grow down - 4K)
+StackBuf equ STACK_TOP-44-32 ; Start the stack here (grow down - 4K)
PartInfo equ StackBuf ; Saved partition table entry
FloppyTable equ PartInfo+16 ; Floppy info table (must follow PartInfo)
OrigFDCTabPtr equ StackBuf-8 ; The 2nd high dword on the stack
@@ -467,9 +467,8 @@ bootsignature dw kaboom.again-bootsec
ldlinux_sys:
-syslinux_banner db 0Dh, 0Ah
- db MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
- db 0Dh, 0Ah, 1Ah ; EOF if we "type" this in DOS
+syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
+ db CR, LF, 1Ah ; EOF if we "type" this in DOS
alignz 8
ldlinux_magic dd LDLINUX_MAGIC
diff --git a/core/idle.inc b/core/idle.inc
index bd134ff6..dc8d2045 100644
--- a/core/idle.inc
+++ b/core/idle.inc
@@ -59,7 +59,7 @@ do_idle:
cmp ax,TICKS_TO_IDLE
jb .done
call [IdleHook]
- cmp word [NoHalt],0
+ cmp dword [NoHalt],0
jne .done
hlt
.done:
@@ -69,8 +69,10 @@ do_idle:
.ret: ret
section .data
+ alignb 4
+NoHalt dw 0 ; NoHalt set by user
+ForceNoHalt dw 0 ; NoHalt forced by hardware config
IdleHook dw do_idle.ret
-NoHalt dw 0
hlt_err db 'ERROR: idle with IF=0', CR, LF, 0
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 2627c2df..23429bdf 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -199,7 +199,7 @@ Files resb MAX_OPEN*open_file_t_size
;; CD-ROM sector (2K) of the file, so the number one priority is actually
;; loading the rest.
;;
-StackBuf equ $-44 ; 44 bytes needed for
+StackBuf equ STACK_TOP-44 ; 44 bytes needed for
; the bootsector chainloading
; code!
OrigESDI equ StackBuf-4 ; The high dword on the stack
@@ -1034,7 +1034,7 @@ writestr_early equ writestr
; Data that needs to be in the first sector
; -----------------------------------------------------------------------------
-syslinux_banner db CR, LF, 'ISOLINUX ', VERSION_STR, ' ', DATE_STR, ' ', 0
+syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
db ' H. Peter Anvin et al', CR, LF, 0
diff --git a/core/kernel.inc b/core/kernel.inc
index 9b888cc8..5e1c7a39 100644
--- a/core/kernel.inc
+++ b/core/kernel.inc
@@ -85,6 +85,8 @@ HEADER_ID equ 'HdrS' ; HdrS (in littleendian hex)
; Flags for the su_loadflags field
;
LOAD_HIGH equ 01h ; Large kernel, load high
+QUIET_FLAG equ 20h ; Quiet the kernel
+KEEP_SEGMENTS equ 40h ; Don't reload segments
CAN_USE_HEAP equ 80h ; Boot loader reports heap size
;
diff --git a/core/layout.inc b/core/layout.inc
index 8c2e2485..19b50579 100644
--- a/core/layout.inc
+++ b/core/layout.inc
@@ -1,7 +1,7 @@
; -----------------------------------------------------------------------
;
; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
;
; 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
@@ -26,6 +26,24 @@ BSS_START equ 0800h
; Text starts at the load address of 07C00h.
TEXT_START equ 7C00h
+;
+; Stack layout
+;
+; PXELINUX: There are apparently some AMI BIOSes in the field which
+; put their BEV stack somewhere below 7C00h (and therefore don't
+; handle localboot properly), so avoid that immediate memory region.
+; The range that is known to be bad is approximately 75E8..7C00; the
+; lower bound is tight.
+;
+ global STACK_LEN, STACK_TOP, STACK_BASE
+STACK_LEN equ 4096
+%if IS_PXELINUX
+STACK_TOP equ 7000h
+%else
+STACK_TOP equ 7c00h
+%endif
+STACK_BASE equ STACK_TOP - STACK_LEN
+
; The secondary BSS section, above the text; we really wish we could
; just make it follow .bcopy32 or hang off the end,
; but it doesn't seem to work that way.
diff --git a/core/ldlinux.asm b/core/ldlinux.asm
index ba7e8040..0808e6e8 100644
--- a/core/ldlinux.asm
+++ b/core/ldlinux.asm
@@ -116,6 +116,7 @@ RootDirSize resd 1 ; Root dir size in sectors
TotalSectors resd 1 ; Total number of sectors
ClustSize resd 1 ; Bytes/cluster
ClustMask resd 1 ; Sectors/cluster - 1
+Clusters resd 1 ; Total number of clusters
CopySuper resb 1 ; Distinguish .bs versus .bss
DriveNumber resb 1 ; BIOS drive number
ClustShift resb 1 ; Shift count for sectors/cluster
@@ -183,24 +184,31 @@ getfattype:
sub eax,[DataArea]
shr eax,cl ; cl == ClustShift
mov cl,nextcluster_fat12-(nextcluster+2)
- cmp eax,4085 ; FAT12 limit
- jb .setsize
+ cmp eax,0xFF4 ; FAT12 limit
+ jbe .setsize
mov cl,nextcluster_fat16-(nextcluster+2)
- cmp eax,65525 ; FAT16 limit
- jb .setsize
+ cmp eax,0xFFF4 ; FAT16 limit
+ jbe .setsize
;
; FAT32, root directory is a cluster chain
;
+ mov ecx,0x0FFFFFF4 ; Max possible cluster count
+ cmp eax,ecx
+ jb .oksize
+ mov eax,ecx
+.oksize:
+
mov cl,[ClustShift]
- mov eax,[bootsec+44] ; Root directory cluster
- sub eax,2
- shl eax,cl
- add eax,[DataArea]
- mov [RootDir],eax
+ mov edx,[bootsec+44] ; Root directory cluster
+ sub edx,2
+ shl edx,cl
+ add edx,[DataArea]
+ mov [RootDir],edx
mov cl,nextcluster_fat28-(nextcluster+2)
mov byte [SuperSize],superblock_len_fat32
.setsize:
mov byte [nextcluster+1],cl
+ mov [Clusters],eax ; Total clusters
;
; Common initialization code
@@ -1242,7 +1250,8 @@ nextcluster_fat12:
shr cx,4
.even: and cx,0FFFh
movzx edi,cx
- cmp di,0FF0h
+ lea ax,[di-2]
+ cmp ax,[Clusters]
pop si
pop cx
pop bx
@@ -1264,7 +1273,8 @@ nextcluster_fat16:
add bx,bx
and bx,1FEh
movzx edi,word [gs:si+bx]
- cmp di,0FFF0h
+ lea ax,[di-2]
+ cmp ax,[Clusters]
pop bx
pop si
pop eax
@@ -1285,7 +1295,8 @@ nextcluster_fat28:
and bx,1FCh
mov edi,dword [gs:si+bx]
and edi,0FFFFFFFh ; 28 bits only
- cmp edi,0FFFFFF0h
+ lea eax,[edi-2]
+ cmp eax,[Clusters]
pop bx
pop si
pop eax
diff --git a/core/pxe.inc b/core/pxe.inc
index 7471c4f0..2fd1edb7 100644
--- a/core/pxe.inc
+++ b/core/pxe.inc
@@ -71,6 +71,7 @@
%define PXENV_GET_FILE_SIZE 0x00e4
%define PXENV_FILE_EXEC 0x00e5
%define PXENV_FILE_API_CHECK 0x00e6
+%define PXENV_FILE_EXIT_HOOK 0x00e7
; Exit codes
%define PXENV_EXIT_SUCCESS 0x0000
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 651dd4c3..edb1584c 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -8,7 +8,7 @@
; MS-DOS floppies.
;
; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
;
; 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
@@ -48,7 +48,7 @@ TFTP_LARGEBLK equ (TFTP_MTU-20-8-4) ; MTU - IP hdr - UDP hdr - TFTP hdr
; Standard TFTP block size
TFTP_BLOCKSIZE_LG2 equ 9 ; log2(bytes/block)
TFTP_BLOCKSIZE equ (1 << TFTP_BLOCKSIZE_LG2)
-%assign USE_PXE_PROVIDED_STACK 1 ; Use stack provided by PXE?
+%assign USE_PXE_PROVIDED_STACK 0 ; Use stack provided by PXE?
SECTOR_SHIFT equ TFTP_BLOCKSIZE_LG2
SECTOR_SIZE equ TFTP_BLOCKSIZE
@@ -212,12 +212,12 @@ pxe_unload_stack_pkt_len equ $-pxe_unload_stack_pkt
packet_buf resb 2048 ; Transfer packet
packet_buf_size equ $-packet_buf
+;
+; Location of the stack.
+;
+StackBuf equ STACK_TOP-44 ; Base of stack if we use our own
+
section .text
- ;
- ; PXELINUX needs more BSS than the other derivatives;
- ; therefore we relocate it from 7C00h on startup.
- ;
-StackBuf equ $ ; Base of stack if we use our own
;
; Primary entry point.
@@ -255,6 +255,21 @@ _start1:
mov ds,ax
mov es,ax
+%if 0 ; debugging code only... not intended for production use
+ ; Clobber the stack segment, to test for specific pathologies
+ mov di,STACK_BASE
+ mov cx,STACK_LEN >> 1
+ mov ax,0xf4f4
+ rep stosw
+
+ ; Clobber the tail of the 64K segment, too
+ extern __bss1_end
+ mov di,__bss1_end
+ sub cx,di ; CX = 0 previously
+ shr cx,1
+ rep stosw
+%endif
+
; That is all pushed onto the PXE stack. Save the pointer
; to it and switch to an internal stack.
mov [InitStack],sp
@@ -332,80 +347,7 @@ adhcp_copy:
mov si,copyright_str
call writestr_early
-;
-; Look to see if we are on an EFI CSM system. Some EFI
-; CSM systems put the BEV stack in low memory, which means
-; a return to the PXE stack will crash the system. However,
-; INT 18h works reliably, so in that case hack the stack and
-; point the "return address" to an INT 18h instruction.
-;
-; Hack the stack instead of the much simpler "just invoke INT 18h
-; if we want to reset", so that chainloading other NBPs will work.
-;
-efi_csm_workaround:
- les bp,[InitStack] ; GS:SP -> original stack
- les bx,[es:bp+44] ; Return address
- cmp word [es:bx],18CDh ; Already pointing to INT 18h?
- je .skip
- ; Search memory from E0000 to FFFFF for a $EFI structure
- mov bx,0E000h
-.scan_mem:
- mov es,bx
- cmp dword [es:0],'IFE$' ; $EFI is byte-reversed...
- jne .not_here
- ;
- ; Verify the table. We don't check the checksum because
- ; it seems some CSMs leave it at zero.
- ;
- movzx cx,byte [es:5] ; Table length
- cmp cx,83 ; 83 bytes is the current length...
- jae .found_it
-
-.not_here:
- inc bx
- jnz .scan_mem
- jmp .skip ; No $EFI structure found
-
- ;
- ; Found a $EFI structure. Move down the original stack
- ; and put an INT 18h instruction there instead.
- ;
-.found_it:
-%if USE_PXE_PROVIDED_STACK
- mov cx,efi_csm_hack_size
- mov si,sp
- sub sp,cx
- mov di,sp
- mov ax,ss
- mov es,ax
- sub [InitStack],cx
- sub [BaseStack],cx
-%else
- les si,[InitStack]
- lea di,[si-efi_csm_hack_size]
- mov [InitStack],di
-%endif
- lea cx,[bp+52] ; End of the stack we care about
- sub cx,si
- es rep movsb
- mov [es:di-8],di ; Clobber the return address
- mov [es:di-6],es
- mov si,efi_csm_hack
- mov cx,efi_csm_hack_size
- rep movsb
-
-.skip:
-
- section .data
- alignz 4
-efi_csm_hack:
- int 18h
- jmp 0F000h:0FFF0h
- hlt
-efi_csm_hack_size equ $-efi_csm_hack
-
- section .text
;
; Assume API version 2.1, in case we find the !PXE structure without
@@ -751,6 +693,33 @@ udp_init:
.success:
;
+; Check to see if we're using gPXE
+;
+%if GPXE
+ ; If we get here, the gPXE status is unknown.
+ mov di,gpxe_file_api_check
+ mov bx,PXENV_FILE_API_CHECK ; BH = 0
+ call pxenv
+ jc .nogood
+ cmp dword [di+4],0xe9c17b20
+ jne .nogood
+ mov eax,[di+12]
+ mov [GPXEFuncs],eax
+ not ax ; Set bits of *missing* functions...
+ and ax,01001011b ; The functions we care about
+ setz bh
+.nogood:
+ mov [HasGPXE],bh
+
+ section .data
+ alignb 4
+GPXEFuncs dd 0
+HasGPXE db 0
+
+ section .text
+%endif
+
+;
; Common initialization code
;
%include "cpuinit.inc"
@@ -947,6 +916,7 @@ local_boot:
mov si,localboot_msg
call writestr_early
; Restore the environment we were called with
+ call reset_pxe
call cleanup_hardware
lss sp,[InitStack]
pop gs
@@ -986,6 +956,7 @@ kaboom:
.wait2: mov dx,[BIOS_timer]
.wait3: call pollchar
jnz .keypress
+ call do_idle
cmp dx,[BIOS_timer]
je .wait3
loop .wait2,ecx
@@ -1599,42 +1570,31 @@ is_gpxe:
jc .ret ; Not a URL, don't bother
.again:
cmp byte [HasGPXE],1
- ja .unknown
+ jnb .ret
; CF=1 if not available (0),
; CF=0 if known available (1).
-.ret: ret
-.unknown:
- ; If we get here, the gPXE status is unknown.
- push es
- pushad
- push ds
- pop es
- mov di,gpxe_file_api_check
- mov bx,PXENV_FILE_API_CHECK ; BH = 0
- call pxenv
- jc .nogood
- cmp dword [di+4],0xe9c17b20
- jne .nogood
- mov ax,[di+12] ; Don't care about the upper half...
- not ax ; Set bits of *missing* functions...
- and ax,01001011b ; The functions we care about
- setz bh
- jz .done
-.nogood:
+ inc word [GPXEWarningCtr]
+ jnz .skip
+
+ push si
mov si,gpxe_warning_msg
- call writestr_early
-.done:
- mov [HasGPXE],bh
- popad
- pop es
- jmp .again
+ call writestr
+ pop si
+.skip:
+ stc
+
+.ret: ret
+
section .data
+ alignz 2
+GPXEWarningCtr:
+ dw -1 ; Print msg when it goes to 0
gpxe_warning_msg:
db 'URL syntax, but gPXE extensions not detected, '
db 'trying plain TFTP...', CR, LF, 0
-HasGPXE db -1 ; Unknown
+
section .text
%endif
@@ -2152,10 +2112,11 @@ get_packet_gpxe:
; This function unloads the PXE and UNDI stacks and unclaims
; the memory.
;
-unload_pxe:
- cmp byte [KeepPXE],0 ; Should we keep PXE around?
- jne reset_pxe
+reset_pxe:
+ or byte [KeepPXE],1
+ ; Fall through
+unload_pxe:
push ds
push es
@@ -2163,6 +2124,9 @@ unload_pxe:
mov ds,ax
mov es,ax
+ cmp byte [KeepPXE],0 ; Should we keep PXE around?
+ jne do_reset_pxe
+
mov si,new_api_unload
cmp byte [APIVer+1],2 ; Major API version >= 2?
jae .new_api
@@ -2233,16 +2197,168 @@ unload_pxe:
; We want to keep PXE around, but still we should reset
; it to the standard bootup configuration
-reset_pxe:
- push es
- push cs
- pop es
+do_reset_pxe:
+ TRACER 'A'
+
mov bx,PXENV_UDP_CLOSE
mov di,pxe_udp_close_pkt
call pxenv
+
+ TRACER 'B'
+
+%if GPXE
+ test byte [GPXEFuncs],80h ; gPXE special unload?
+ jz .plain
+
+ TRACER 'C'
+
+ mov bx,PXENV_FILE_EXIT_HOOK
+ mov di,pxe_file_exit_hook
+ call pxenv
+ jc .plain
+
+ TRACER 'D'
+
+ ; Now we actually need to exit back to gPXE, which will
+ ; give control back to us on the *new* "original stack"...
+ pushfd
+ pushad
+ push ds
+ push fs
+ push gs
+ mov [PXEStack],sp
+ mov [PXEStack+2],ss
+ lss sp,[InitStack]
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ popad
+ popfd
+ xor ax,ax
+ retf
+.resume:
+ cli
+
+ TRACER 'E'
+
+ ; gPXE will have a stack frame looking much like our
+ ; InitStack, except it has a magic cookie at the top,
+ ; and the segment registers are in reverse order.
+ pop eax
+ pop ax
+ pop bx
+ pop cx
+ pop dx
+ push ax
+ push bx
+ push cx
+ push dx
+ mov [cs:InitStack],sp
+ mov [cs:InitStack+2],ss
+ lss sp,[cs:PXEStack]
+ pop gs
+ pop fs
+ pop ds
+ popad
+ popfd
+%endif ; GPXE
+
+.plain:
+ TRACER 'F'
+
+;
+; Look to see if we are on an EFI CSM system. Some EFI CSM systems
+; (AMI CSM) put the BEV stack in low memory (just below 64K), which
+; means a return to the PXE stack will crash the system. However, INT
+; 18h works reliably, so in that case hack the stack and point the
+; "return address" to an INT 18h instruction.
+;
+; Hack the stack instead of the much simpler "just invoke INT 18h
+; if we want to reset", so that chainloading other NBPs will work.
+;
+efi_csm_workaround:
+ les bp,[InitStack] ; ES:BP -> original stack
+ les bx,[es:bp+44] ; ES:BX -> Return address
+ cmp word [es:bx],18CDh ; Already pointing to INT 18h?
+ je .skip
+
+ ; Search memory from E0000 to FFFFF for a $EFI structure
+ mov bx,0E000h
+.scan_mem:
+ mov es,bx
+ cmp dword [es:0],'IFE$' ; $EFI is byte-reversed...
+ jne .not_here
+ ;
+ ; Verify the table. We don't check the checksum because
+ ; it seems some CSMs leave it at zero.
+ ;
+ movzx cx,byte [es:5] ; Table length
+ cmp cx,83 ; 83 bytes is the current length...
+ jae .found_it
+
+.not_here:
+ inc bx
+ jnz .scan_mem
+ jmp .skip ; No $EFI structure found
+
+ ;
+ ; Found a $EFI structure. Move down the original stack
+ ; and put an INT 18h instruction there instead.
+ ;
+.found_it:
+%if USE_PXE_PROVIDED_STACK
+ mov cx,efi_csm_hack_size
+ mov si,sp
+ sub sp,cx
+ mov di,sp
+ mov ax,ss
+ mov es,ax
+ sub [InitStack],cx
+ sub [BaseStack],cx
+%else
+ les si,[InitStack]
+ lea di,[si-efi_csm_hack_size]
+ mov [InitStack],di
+%endif
+ lea cx,[bp+52] ; End of the stack we care about
+ sub cx,si
+ es rep movsb
+ mov [es:di-8],di ; Clobber the return address
+ mov [es:di-6],es
+ mov si,efi_csm_hack
+ mov cx,efi_csm_hack_size
+ rep movsb
+
+.skip:
+ TRACER 'G'
+
+.done:
pop es
+ pop ds
ret
+
+ section .data
+ alignz 4
+efi_csm_hack:
+ int 18h
+ jmp 0F000h:0FFF0h
+ hlt
+efi_csm_hack_size equ $-efi_csm_hack
+
+
+
+%if GPXE
+ alignz 4
+pxe_file_exit_hook:
+.status: dw 0
+.offset: dw do_reset_pxe.resume
+.seg: dw 0
+%endif
+
+ section .text
+
;
; gendotquad
;
@@ -2757,7 +2873,7 @@ tftpprefix_msg db 'TFTP prefix: ', 0
localboot_msg db 'Booting from local disk...', CR, LF, 0
trying_msg db 'Trying to load: ', 0
default_str db 'default', 0
-syslinux_banner db CR, LF, 'PXELINUX ', VERSION_STR, ' ', DATE_STR, ' ', 0
+syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
cfgprefix db 'pxelinux.cfg/' ; No final null!
cfgprefix_len equ ($-cfgprefix)
diff --git a/core/runkernel.inc b/core/runkernel.inc
index 8bfc8b8d..e738706f 100644
--- a/core/runkernel.inc
+++ b/core/runkernel.inc
@@ -1,7 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+;; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
;;
;; 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
@@ -138,15 +138,18 @@ parse_cmdline:
jmp .next_opt
opt_vga:
- mov eax,[es:di-1]
+ mov ax,[es:di-1]
mov bx,-1
- cmp eax,'=nor' ; vga=normal
+ cmp ax,'=n' ; vga=normal
je .vc0
dec bx ; bx <- -2
- cmp eax,'=ext' ; vga=ext
+ cmp ax,'=e' ; vga=ext
je .vc0
dec bx ; bx <- -3
- cmp eax,'=ask' ; vga=ask
+ cmp ax,'=a' ; vga=ask
+ je .vc0
+ mov bx,0x0f04 ; bx <- 0x0f04 (current mode)
+ cmp ax,'=c' ; vga=current
je .vc0
call parseint_esdi ; vga=<number>
jc .skip ; Not an integer
@@ -165,7 +168,7 @@ opt_mem:
ret
opt_quiet:
- mov byte [QuietBoot],1
+ mov byte [QuietBoot],QUIET_FLAG
ret
%if IS_PXELINUX
@@ -225,6 +228,8 @@ new_kernel:
; we were provided.
;
mov al,[es:su_loadflags]
+ or al,[QuietBoot] ; Set QUIET_FLAG if needed
+ mov [es:su_loadflags],al
mov [LoadFlags],al
any_kernel:
@@ -454,7 +459,10 @@ setup_move:
; BX points to the final real mode segment, and will be loaded
; into DS.
- jmp replace_bootstrap
+
+ test byte [QuietBoot],QUIET_FLAG
+ jz replace_bootstrap
+ jmp replace_bootstrap_noclearmode
run_linux_kernel:
;
@@ -625,7 +633,7 @@ loadinitrd:
; assumes CS == DS
;
writestr_qchk:
- test byte [QuietBoot],01h
+ test byte [QuietBoot],QUIET_FLAG
jz writestr
ret
diff --git a/core/syslinux.ld b/core/syslinux.ld
index c1da230e..f6446e1b 100644
--- a/core/syslinux.ld
+++ b/core/syslinux.ld
@@ -20,8 +20,6 @@ OUTPUT_ARCH(i386)
EXTERN(_start)
ENTRY(_start)
-STACK_LEN = 4096;
-
SECTIONS
{
/* "Early" sections (before the load) */
@@ -63,7 +61,6 @@ SECTIONS
/* Stack */
- STACK_BASE = 0x7c00 - STACK_LEN;
. = STACK_BASE;
.stack : AT(STACK_BASE) {
__stack_start = .;
diff --git a/core/ui.inc b/core/ui.inc
index 1b40717a..ed96ccdc 100644
--- a/core/ui.inc
+++ b/core/ui.inc
@@ -1,7 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+;; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
;;
;; 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
@@ -292,12 +292,27 @@ show_network_info:
; Jump here to run the default command line
;
auto_boot:
+ cmp word [DefaultLevel],0 ; No UI or DEFAULT?
+ jne .have_default
+ mov si,no_default_msg
+ call writestr
+ cmp word [NoEscape],0 ; NOESCAPE but no DEFAULT?
+ jne kaboom ; If so, we're stuck!
+ jmp enter_command
+
+.have_default:
mov si,default_cmd
mov di,command_line
mov cx,(max_cmd_len+4) >> 2
rep movsd
jmp short load_kernel
+ section .data
+no_default_msg db 'No DEFAULT or UI configuration directive found!'
+ db CR, LF, 0
+
+ section .text
+
;
; Jump here when the command line is completed
;
@@ -529,6 +544,7 @@ getchar_timeout:
push word [BIOS_timer]
call pollchar
jnz .got_char
+ call do_idle
pop ax
cmp ax,[BIOS_timer] ; Has the timer advanced?
je .loop
diff --git a/doc/comboot.txt b/doc/comboot.txt
index b3d8e648..eb437086 100644
--- a/doc/comboot.txt
+++ b/doc/comboot.txt
@@ -79,7 +79,7 @@ The following arguments are passed to the program on the stack:
Address Size Meaning
[ESP] dword Return (termination) address
- [ESP+4] dword Number of additional arguments (currently 7)
+ [ESP+4] dword Number of additional arguments (currently 8)
[ESP+8] dword Pointer to the command line arguments (null-terminated string)
[ESP+12] dword Pointer to INT call helper function
[ESP+16] dword Pointer to low memory bounce buffer
@@ -87,19 +87,7 @@ The following arguments are passed to the program on the stack:
[ESP+24] dword Pointer to FAR call helper function (new in 2.05)
[ESP+28] dword Pointer to CDECL helper function (new in 3.54)
[ESP+32] dword Amount of memory controlled by the Syslinux core (new in 3.74)
-
-This corresponds to the following C prototype, available in the file
-com32/include/com32.h:
-
-/* The standard prototype for _start() */
-int _start(unsigned int __nargs,
- char *__cmdline,
- void (*__intcall)(uint8_t, com32sys_t *, com32sys_t *),
- void *__bounce_ptr,
- unsigned int __bounce_len,
- void (*__farcall)(uint32_t, com32sys_t *, com32sys_t *),
- int (*__cfarcall)(uint32_t, void *, size_t)
- );
+ [ESP+36] dword Pointer to the filename of the com32 module (new in 3.86)
The intcall helper function can be used to issue BIOS or Syslinux API
calls, and takes the interrupt number as first argument. The second
@@ -248,6 +236,10 @@ AX=0001h [2.00] Get Version
This API call returns the Syslinux version and API
information.
+ Note: before version 3.86, the version string had a leading CR LF
+ and the copyright string had a leading space. The strings might
+ still contain trailing CR and/or LF.
+
AX=0002h [2.01] Write String
@@ -401,6 +393,7 @@ AX=000Ah [2.00] Get Derivative-Specific Information
Input: AX 000Ah
Output: AL 32h (PXELINUX)
DX PXE API version detected (DH=major, DL=minor)
+ ECX Local IP number (network byte order) [3.85]
ES:BX pointer to PXENV+ or !PXE structure
FS:SI pointer to original stack with invocation record
diff --git a/doc/memdisk.txt b/doc/memdisk.txt
index 254cb7c9..c7244abc 100644
--- a/doc/memdisk.txt
+++ b/doc/memdisk.txt
@@ -132,15 +132,22 @@ g) The following option can be used to set the real-mode stack size.
stack=size Set the stack to "size" bytes
+h) Some systems without a floppy drive have been known to have
+ problems with floppy images. To avoid that those problems, first
+ of all make sure you don't have a floppy drive configured on the
+ BIOS screen. If there is no option to configure that, or that
+ doesn't work, you can use the option:
+
+ nopass Hide all real drives of the same type (floppy or hard disk)
+
Some interesting things to note:
If you're using MEMDISK to boot DOS from a CD-ROM (using ISOLINUX),
you might find the generic El Torito CD-ROM driver by Gary Tong and
-Bart Lagerweij useful:
-
- http://www.nu2.nu/eltorito/
-
+Bart Lagerweij useful. It is now included with the Syslinux
+distribution, in the dosutil directory. See the file
+dosutil/eltorito.txt for more information.
Similarly, if you're booting DOS over the network using PXELINUX, you
can use the "keeppxe" option and use the generic PXE (UNDI) NDIS
diff --git a/doc/menu.txt b/doc/menu.txt
index e1601249..c912c1df 100644
--- a/doc/menu.txt
+++ b/doc/menu.txt
@@ -48,6 +48,14 @@ MENU HIDDEN
All that is displayed is a timeout message.
+MENU CLEAR
+
+ Clear the screen when exiting the menu, instead of leaving the
+ menu displayed. For vesamenu, this means the graphical
+ background is still displayed without the menu itself for as
+ long as the screen remains in graphics mode.
+
+
MENU SHIFTKEY
Exit the menu system immediately unless either the Shift or Alt
diff --git a/doc/syslinux.txt b/doc/syslinux.txt
index f654bffd..76cae245 100644
--- a/doc/syslinux.txt
+++ b/doc/syslinux.txt
@@ -2,7 +2,7 @@
A suite of bootloaders for Linux
- Copyright 1994-2009 H. Peter Anvin and contributors
+ Copyright 1994-2010 H. Peter Anvin and contributors
This program is provided under the terms of the GNU General Public
License, version 2 or, at your option, any later version. There is no
@@ -90,10 +90,6 @@ For the DOS and Windows installers, the -m and -a options can be used
on hard drives to write a Master Boot Record (MBR), and to mark the
specific partition active.
-On boot time, by default, the kernel will be loaded from the image named
-LINUX on the boot floppy. This default can be changed, see the section
-on the Syslinux config file.
-
If the Shift or Alt keys are held down during boot, or the Caps or Scroll
locks are set, Syslinux will display a LILO-style "boot:" prompt. The
user can then type a kernel file name followed by any kernel parameters.
@@ -140,14 +136,9 @@ DEFAULT kernel options...
it will act just as if the entries after DEFAULT had been typed
in at the "boot:" prompt.
- If no configuration file is present, or no DEFAULT entry is
- present in the config file, the default is "linux auto".
-
- NOTE: Earlier versions of Syslinux used to automatically
- append the string "auto" to whatever the user specified using
- the DEFAULT command. As of version 1.54, this is no longer
- true, as it caused problems when using a shell as a substitute
- for "init." You may want to include this option manually.
+ If no configuration file is present, or no DEFAULT entry is
+ present in the config file, an error message is displayed and
+ the boot: prompt is shown.
UI module options...
Selects a specific user interface module (typically menu.c32
diff --git a/dos/Makefile b/dos/Makefile
index 9d8ce33c..eb0ca1a6 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -36,7 +36,7 @@ LIBOBJS = int2526.o conio.o memcpy.o memset.o skipatou.o atou.o \
VPATH = .:../libfat:../libinstaller
-TARGETS = syslinux.com copybs.com
+TARGETS = syslinux.com
all: $(TARGETS)
diff --git a/dosutil/Makefile b/dosutil/Makefile
index 53b3859a..fc10ff90 100644
--- a/dosutil/Makefile
+++ b/dosutil/Makefile
@@ -12,7 +12,9 @@ UPX = upx
NASM = nasm
NASMOPT = -O9999
-TARGETS = mdiskchk.com eltorito.sys
+WCTARGETS = mdiskchk.com
+NSTARGETS = eltorito.sys copybs.com
+TARGETS = $(WCTARGETS) $(NSTARGETS)
%.obj: %.c
$(WCL) $(WCLOPT) -c -fo=$@ $<
@@ -22,28 +24,34 @@ TARGETS = mdiskchk.com eltorito.sys
$(UPX) --ultra-brute --lzma $@ || \
$(UPX) --ultra-brute $@ || \
true
+ rm -f $*.0*
+ chmod a-x $@
%.sys: %.asm
$(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $<
$(UPX) --ultra-brute --lzma $@ || \
$(UPX) --ultra-brute $@ || \
true
+ rm -f $*.0*
+ chmod a-x $@
%.com: %.asm
$(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $<
$(UPX) --ultra-brute --lzma $@ || \
$(UPX) --ultra-brute $@ || \
true
+ rm -f $*.0*
+ chmod a-x $@
all: $(TARGETS)
tidy dist:
- -rm -f *.obj *.lst *.o
+ -rm -f *.obj *.lst *.o *.0*
clean: tidy
spotless: clean
- -rm -f *.com *.sys *~
+ -rm -f $(NSTARGETS) *~
installer: all
diff --git a/dos/copybs.asm b/dosutil/copybs.asm
index 26407148..26407148 100644
--- a/dos/copybs.asm
+++ b/dosutil/copybs.asm
diff --git a/dosutil/eltorito.asm b/dosutil/eltorito.asm
index 1ff8b38c..eabda126 100644
--- a/dosutil/eltorito.asm
+++ b/dosutil/eltorito.asm
@@ -71,10 +71,11 @@ DriveLetter db 0 ; |
NumUnitsSupp db 1 ;-+
DriverName db 'El-Torito CD-ROM Device Driver',0
-ReqHdrLoc dw 0,0 ; 35h
-DriveNumber db 0 ; 39h
-XferAddr dw 0,0 ; 3ah
-Checksum dw -1,-1
+ align 4, db 0
+ReqHdrLoc dd 0
+XferAddr dd 0
+Checksum dd -1
+DriveNumber db 0
ReadBytes db 0 ;0 --> 2048 bytes/sector
;1 --> 1024 bytes/sector
;2 --> 512 bytes/sector
diff --git a/dosutil/mdiskchk.com b/dosutil/mdiskchk.com
index 78257519..78257519 100755..100644
--- a/dosutil/mdiskchk.com
+++ b/dosutil/mdiskchk.com
Binary files differ
diff --git a/extlinux/Makefile b/extlinux/Makefile
index 48105338..23ffd400 100644
--- a/extlinux/Makefile
+++ b/extlinux/Makefile
@@ -19,7 +19,7 @@ include $(topdir)/MCONFIG
OPTFLAGS = -g -Os
INCLUDES = -I. -I.. -I../libinstaller
-CFLAGS = -W -Wall -Wno-sign-compare -D_FILE_OFFSET_BITS=64 \
+CFLAGS = $(GCCWARN) -Wno-sign-compare -D_FILE_OFFSET_BITS=64 \
$(OPTFLAGS) $(INCLUDES)
LDFLAGS = # -s
diff --git a/gen-id.sh b/gen-id.sh
index 1b3e108b..301ea4eb 100755
--- a/gen-id.sh
+++ b/gen-id.sh
@@ -8,9 +8,10 @@
#
ver="$1"
-tim="$1"
+tim="$2"
+top=`dirname "$0"`
-if test -n "$GIT_DIR" -o -d ../.git -o -f ../.git; then
+if test -n "$GIT_DIR" -o -d "$top"/.git -o -f "$top"/.git; then
id="$(git describe)"
if test -n "$id"; then
if test x"$(echo "$id" | cut -d- -f1)" = xsyslinux; then
diff --git a/gpxe/gpxe.diff b/gpxe/gpxe.diff
new file mode 100644
index 00000000..57e5f416
--- /dev/null
+++ b/gpxe/gpxe.diff
@@ -0,0 +1,73 @@
+diff --git a/gpxe/src/config/general.h b/gpxe/src/config/general.h
+index 0a9e625..de51f9f 100644
+--- a/gpxe/src/config/general.h
++++ b/gpxe/src/config/general.h
+@@ -55,8 +55,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
+
+ #define DOWNLOAD_PROTO_TFTP /* Trivial File Transfer Protocol */
+ #define DOWNLOAD_PROTO_HTTP /* Hypertext Transfer Protocol */
+-#undef DOWNLOAD_PROTO_HTTPS /* Secure Hypertext Transfer Protocol */
+-#undef DOWNLOAD_PROTO_FTP /* File Transfer Protocol */
++#define DOWNLOAD_PROTO_HTTPS /* Secure Hypertext Transfer Protocol */
++#define DOWNLOAD_PROTO_FTP /* File Transfer Protocol */
+ #undef DOWNLOAD_PROTO_TFTM /* Multicast Trivial File Transfer Protocol */
+ #undef DOWNLOAD_PROTO_SLAM /* Scalable Local Area Multicast */
+
+diff --git a/gpxe/src/config/general.h b/gpxe/src/config/general.h
+index de51f9f..2f5a938 100644
+--- a/gpxe/src/config/general.h
++++ b/gpxe/src/config/general.h
+@@ -31,7 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
+ * Timer configuration
+ *
+ */
+-#define BANNER_TIMEOUT 20 /* Tenths of a second for which the shell
++#define BANNER_TIMEOUT 0 /* Tenths of a second for which the shell
+ banner should appear */
+
+ /*
+diff --git a/gpxe/src/hci/shell_banner.c b/gpxe/src/hci/shell_banner.c
+index 8afefe3..b92e08e 100644
+--- a/gpxe/src/hci/shell_banner.c
++++ b/gpxe/src/hci/shell_banner.c
+@@ -41,6 +41,9 @@ int shell_banner ( void ) {
+ int wait_count;
+ int key;
+
++ if ( BANNER_TIMEOUT <= 0 )
++ return enter_shell;
++
+ printf ( "\nPress Ctrl-B for the gPXE command line..." );
+
+ /* Wait for key */
+diff --git a/gpxe/src/include/gpxe/tcp.h b/gpxe/src/include/gpxe/tcp.h
+index 7ae7eab..9dc39fc 100644
+--- a/gpxe/src/include/gpxe/tcp.h
++++ b/gpxe/src/include/gpxe/tcp.h
+@@ -286,8 +286,8 @@ struct tcp_options {
+ * actually use 65536, we use a window size of (65536-4) to ensure
+ * that payloads remain dword-aligned.
+ */
+-//#define TCP_MAX_WINDOW_SIZE ( 65536 - 4 )
+-#define TCP_MAX_WINDOW_SIZE 4096
++#define TCP_MAX_WINDOW_SIZE ( 65536 - 4 )
++//#define TCP_MAX_WINDOW_SIZE 4096
+
+ /**
+ * Path MTU
+diff --git a/gpxe/src/core/malloc.c b/gpxe/src/core/malloc.c
+index 8b0bc24..0153748 100644
+--- a/gpxe/src/core/malloc.c
++++ b/gpxe/src/core/malloc.c
+@@ -78,9 +78,9 @@ size_t freemem;
+ /**
+ * Heap size
+ *
+- * Currently fixed at 128kB.
++ * Currently fixed at 512kB.
+ */
+-#define HEAP_SIZE ( 128 * 1024 )
++#define HEAP_SIZE ( 512 * 1024 )
+
+ /** The heap itself */
+ static char heap[HEAP_SIZE] __attribute__ (( aligned ( __alignof__(void *) )));
diff --git a/gpxe/pxelinux.gpxe b/gpxe/pxelinux.gpxe
index 51fe222e..c267d136 100644
--- a/gpxe/pxelinux.gpxe
+++ b/gpxe/pxelinux.gpxe
@@ -1,4 +1,5 @@
#!gpxe
+set use-cached 1
dhcp net0
imgload pxelinux.0
boot pxelinux.0
diff --git a/gpxe/src/Makefile b/gpxe/src/Makefile
index a627d967..cc91d78f 100644
--- a/gpxe/src/Makefile
+++ b/gpxe/src/Makefile
@@ -22,7 +22,7 @@ ECHO := echo
PRINTF := printf
PERL := /usr/bin/perl
CC := $(CROSS_COMPILE)gcc
-CPP := $(CROSS_COMPILE)gcc -E -Wp,-Wall
+CPP := $(CC) -E
AS := $(CROSS_COMPILE)as
LD := $(CROSS_COMPILE)ld
SIZE := $(CROSS_COMPILE)size
@@ -35,12 +35,17 @@ PARSEROM := $(PERL) ./util/parserom.pl
MAKEROM := $(PERL) ./util/makerom.pl
SYMCHECK := $(PERL) ./util/symcheck.pl
SORTOBJDUMP := $(PERL) ./util/sortobjdump.pl
+PADIMG := $(PERL) ./util/padimg.pl
+LICENCE := $(PERL) ./util/licence.pl
NRV2B := ./util/nrv2b
ZBIN := ./util/zbin
ELF2EFI32 := ./util/elf2efi32
ELF2EFI64 := ./util/elf2efi64
EFIROM := ./util/efirom
+ICCFIX := ./util/iccfix
DOXYGEN := doxygen
+BINUTILS_DIR := /usr
+BFD_DIR := $(BINUTILS_DIR)
###############################################################################
#
@@ -49,13 +54,14 @@ DOXYGEN := doxygen
SRCDIRS :=
SRCDIRS += libgcc
SRCDIRS += core
-SRCDIRS += proto
-SRCDIRS += net net/tcp net/udp
+SRCDIRS += net net/tcp net/udp net/infiniband net/80211
SRCDIRS += image
SRCDIRS += drivers/bus
SRCDIRS += drivers/net
SRCDIRS += drivers/net/e1000
SRCDIRS += drivers/net/phantom
+SRCDIRS += drivers/net/rtl818x
+SRCDIRS += drivers/net/ath5k
SRCDIRS += drivers/block
SRCDIRS += drivers/nvs
SRCDIRS += drivers/bitbash
@@ -66,6 +72,7 @@ SRCDIRS += crypto crypto/axtls crypto/matrixssl
SRCDIRS += hci hci/commands hci/tui
SRCDIRS += hci/mucurses hci/mucurses/widgets
SRCDIRS += usr
+SRCDIRS += config
# NON_AUTO_SRCS lists files that are excluded from the normal
# automatic build system.
@@ -73,6 +80,11 @@ SRCDIRS += usr
NON_AUTO_SRCS :=
NON_AUTO_SRCS += drivers/net/prism2.c
+# INCDIRS lists the include path
+#
+INCDIRS :=
+INCDIRS += include .
+
###############################################################################
#
# Default build target: build the most common targets and print out a
@@ -115,9 +127,9 @@ install :
#
# Version number calculations
#
-VERSION_MAJOR = 0
-VERSION_MINOR = 9
-VERSION_PATCH = 7
+VERSION_MAJOR = 1
+VERSION_MINOR = 0
+VERSION_PATCH = 0
EXTRAVERSION =
MM_VERSION = $(VERSION_MAJOR).$(VERSION_MINOR)
VERSION = $(MM_VERSION).$(VERSION_PATCH)$(EXTRAVERSION)
diff --git a/gpxe/src/Makefile.housekeeping b/gpxe/src/Makefile.housekeeping
index 2ab842e6..1f5e115f 100644
--- a/gpxe/src/Makefile.housekeeping
+++ b/gpxe/src/Makefile.housekeeping
@@ -54,6 +54,14 @@ echo :
###############################################################################
#
+# Generate a usable "seq" substitute
+#
+define seq
+ $(shell awk 'BEGIN { for ( i = $(1) ; i <= $(2) ; i++ ) print i }')
+endef
+
+###############################################################################
+#
# Determine host OS
#
HOST_OS := $(shell uname -s)
@@ -62,6 +70,22 @@ hostos :
###############################################################################
#
+# Determine compiler
+
+CCDEFS := $(shell $(CC) -E -x c -c /dev/null -dM | cut -d" " -f2)
+ccdefs:
+ @$(ECHO) $(CCDEFS)
+
+ifeq ($(filter __ICC,$(CCDEFS)),__ICC)
+CCTYPE := icc
+else
+CCTYPE := gcc
+endif
+cctype:
+ @$(ECHO) $(CCTYPE)
+
+###############################################################################
+#
# Check for tools that can cause failed builds
#
.toolcheck :
@@ -103,10 +127,30 @@ oldgas :
# default, even when -ffreestanding is specified. We therefore need
# to disable -fstack-protector if the compiler supports it.
#
+ifeq ($(CCTYPE),gcc)
SP_TEST = $(CC) -fno-stack-protector -x c -c /dev/null \
-o /dev/null >/dev/null 2>&1
SP_FLAGS := $(shell $(SP_TEST) && $(ECHO) '-fno-stack-protector')
CFLAGS += $(SP_FLAGS)
+endif
+
+# gcc 4.4 generates .eh_frame sections by default, which distort the
+# output of "size". Inhibit this.
+#
+ifeq ($(CCTYPE),gcc)
+CFI_TEST = $(CC) -fno-dwarf2-cfi-asm -x c -c /dev/null \
+ -o /dev/null >/dev/null 2>&1
+CFI_FLAGS := $(shell $(CFI_TEST) && $(ECHO) '-fno-dwarf2-cfi-asm')
+CFLAGS += $(CFI_FLAGS)
+endif
+
+# Some versions of gas choke on division operators, treating them as
+# comment markers. Specifying --divide will work around this problem,
+# but isn't available on older gas versions.
+#
+DIVIDE_TEST = $(AS) --divide /dev/null -o /dev/null 2>/dev/null
+DIVIDE_FLAGS := $(shell $(DIVIDE_TEST) && $(ECHO) '--divide')
+ASFLAGS += $(DIVIDE_FLAGS)
###############################################################################
#
@@ -248,6 +292,11 @@ MAKEDEPS += arch/$(ARCH)/Makefile
include arch/$(ARCH)/Makefile
endif
+# Include architecture-specific include path
+ifdef ARCH
+INCDIRS += arch/$(ARCH)/include
+endif
+
###############################################################################
#
# Source file handling
@@ -276,12 +325,45 @@ autosrcs :
ifdef BIN
+# INCDIRS lists the include path
+incdirs :
+ @$(ECHO) $(INCDIRS)
+
# Common flags
#
-CFLAGS += -I include -I arch/$(ARCH)/include -I .
-CFLAGS += -Os -ffreestanding
-CFLAGS += -Wall -W -Wformat-nonliteral
+CFLAGS += $(foreach INC,$(INCDIRS),-I$(INC))
+CFLAGS += -Os
CFLAGS += -g
+ifeq ($(CCTYPE),gcc)
+CFLAGS += -ffreestanding
+CFLAGS += -Wall -W -Wformat-nonliteral
+endif
+ifeq ($(CCTYPE),icc)
+CFLAGS += -fno-builtin
+CFLAGS += -no-ip
+CFLAGS += -no-gcc
+CFLAGS += -diag-disable 111 # Unreachable code
+CFLAGS += -diag-disable 128 # Unreachable loop
+CFLAGS += -diag-disable 170 # Array boundary checks
+CFLAGS += -diag-disable 177 # Unused functions
+CFLAGS += -diag-disable 181 # printf() format checks
+CFLAGS += -diag-disable 188 # enum strictness
+CFLAGS += -diag-disable 193 # Undefined preprocessor identifiers
+CFLAGS += -diag-disable 280 # switch ( constant )
+CFLAGS += -diag-disable 310 # K&R parameter lists
+CFLAGS += -diag-disable 424 # Extra semicolon
+CFLAGS += -diag-disable 589 # Declarations mid-code
+CFLAGS += -diag-disable 593 # Unused variables
+CFLAGS += -diag-disable 810 # Casting ints to smaller ints
+CFLAGS += -diag-disable 981 # Sequence point violations
+CFLAGS += -diag-disable 1292 # Ignored attributes
+CFLAGS += -diag-disable 1338 # void pointer arithmetic
+CFLAGS += -diag-disable 1361 # Variable-length arrays
+CFLAGS += -diag-disable 1418 # Missing prototypes
+CFLAGS += -diag-disable 1419 # Missing prototypes
+CFLAGS += -diag-disable 1599 # Hidden variables
+CFLAGS += -Wall -Wmissing-declarations
+endif
CFLAGS += $(EXTRA_CFLAGS)
ASFLAGS += $(EXTRA_ASFLAGS)
LDFLAGS += $(EXTRA_LDFLAGS)
@@ -314,11 +396,21 @@ OBJ_CFLAGS = $(CFLAGS_$(OBJECT)) -DOBJECT=$(subst -,_,$(OBJECT))
$(BIN)/%.flags :
@$(ECHO) $(OBJ_CFLAGS)
+# ICC requires postprocessing objects to fix up table alignments
+#
+ifeq ($(CCTYPE),icc)
+POST_O = && $(ICCFIX) $@
+POST_O_DEPS := $(ICCFIX)
+else
+POST_O :=
+POST_O_DEPS :=
+endif
+
# Rules for specific object types.
#
COMPILE_c = $(CC) $(CFLAGS) $(CFLAGS_c) $(OBJ_CFLAGS)
-RULE_c = $(Q)$(COMPILE_c) -c $< -o $@
-RULE_c_to_dbg%.o = $(Q)$(COMPILE_c) -Ddebug_$(OBJECT)=$* -c $< -o $@
+RULE_c = $(Q)$(COMPILE_c) -c $< -o $@ $(POST_O)
+RULE_c_to_dbg%.o = $(Q)$(COMPILE_c) -Ddebug_$(subst -,_,$(OBJECT))=$* -c $< -o $@ $(POST_O)
RULE_c_to_c = $(Q)$(COMPILE_c) -E -c $< > $@
RULE_c_to_s = $(Q)$(COMPILE_c) -S -g0 -c $< -o $@
@@ -346,39 +438,25 @@ define src_template
@$(MKDIR) -p $(dir $(2))
@$(RM) $(2)
@$(TOUCH) $(2)
- $(foreach OBJ,$(if $(OBJS_$(4)),$(OBJS_$(4)),$(4)), \
- $(call obj_template,$(1),$(2),$(3),$(OBJ)))
- @$(PARSEROM) $(1) >> $(2)
-
-endef
-
-# obj_template : generate Makefile rules for a given resultant object
-# of a particular source file. (We can have multiple objects per
-# source file via the OBJS_xxx list.)
-#
-# $(1) is the full path to the source file (e.g. "drivers/net/rtl8139.c")
-# $(2) is the full path to the .d file (e.g. "bin/deps/drivers/net/rtl8139.d")
-# $(3) is the source type (e.g. "c")
-# $(4) is the object name (e.g. "rtl8139")
-#
-define obj_template
-
@$(CPP) $(CFLAGS) $(CFLAGS_$(3)) $(CFLAGS_$(4)) -DOBJECT=$(4) \
- -Wno-error -MM $(1) -MT "$(4)_DEPS" -MG -MP | \
- sed 's/_DEPS\s*:/_DEPS =/' >> $(2)
- @$(ECHO_E) '\n$$(BIN)/$(4).o : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
+ -Wno-error -MM $(1) -MG -MP | \
+ sed 's/\.o\s*:/_DEPS =/' >> $(2)
+ @$(ECHO_E) '\n$$(BIN)/$(4).o :' \
+ '$(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(4)_DEPS)' \
'\n\t$$(QM)$(ECHO) " [BUILD] $$@"' \
'\n\t$$(RULE_$(3))\n' \
'\nBOBJS += $$(BIN)/$(4).o\n' \
$(foreach TGT,$(DEBUG_TARGETS), \
$(if $(RULE_$(3)_to_$(TGT)), \
- '\n$$(BIN)/$(4).$(TGT) : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
+ '\n$$(BIN)/$(4).$(TGT) :' \
+ '$(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(4)_DEPS)' \
'\n\t$$(QM)$(ECHO) " [BUILD] $$@"' \
'\n\t$$(RULE_$(3)_to_$(TGT))\n' \
'\n$(TGT)_OBJS += $$(BIN)/$(4).$(TGT)\n' ) ) \
'\n$(2) : $$($(4)_DEPS)\n' \
'\nTAGS : $$($(4)_DEPS)\n' \
>> $(2)
+ @$(PARSEROM) $(1) >> $(2)
endef
@@ -415,7 +493,7 @@ roms :
#
EMBEDDED_LIST := $(BIN)/.embedded.list
ifeq ($(wildcard $(EMBEDDED_LIST)),)
-EMBEDDED_LIST_IMAGE :=
+EMBEDDED_LIST_IMAGE := <invalid>
else
EMBEDDED_LIST_IMAGE := $(shell cat $(EMBEDDED_LIST))
endif
@@ -428,7 +506,7 @@ $(EMBEDDED_LIST) :
VERYCLEANUP += $(EMBEDDED_LIST)
EMBEDDED_FILES := $(subst $(COMMA), ,$(EMBEDDED_IMAGE))
-EMBED_ALL := $(foreach i,$(shell seq 1 $(words $(EMBEDDED_FILES))),\
+EMBED_ALL := $(foreach i,$(call seq,1,$(words $(EMBEDDED_FILES))),\
EMBED ( $(i), \"$(word $(i), $(EMBEDDED_FILES))\",\
\"$(notdir $(word $(i),$(EMBEDDED_FILES)))\" ))
@@ -550,7 +628,7 @@ $(BIN)/%.info :
#
BLIB_LIST := $(BIN)/.blib.list
ifeq ($(wildcard $(BLIB_LIST)),)
-BLIB_LIST_OBJS :=
+BLIB_LIST_OBJS := <invalid>
else
BLIB_LIST_OBJS := $(shell cat $(BLIB_LIST))
endif
@@ -589,6 +667,55 @@ $(BIN)/%.tmp : $(BLIB) $(MAKEDEPS) $(LDSCRIPT)
$(BIN)/%.map : $(BIN)/%.tmp
@less $(BIN)/$*.tmp.map
+# Get objects list for the specified target
+#
+define objs_list
+ $(sort $(foreach OBJ_SYMBOL,\
+ $(filter obj_%,$(shell $(NM) $(1) | cut -d" " -f3)),\
+ $(patsubst obj_%,%,$(OBJ_SYMBOL))))
+endef
+$(BIN)/%.objs : $(BIN)/%.tmp
+ $(Q)$(ECHO) $(call objs_list,$<)
+$(BIN)/%.sizes : $(BIN)/%.tmp
+ $(Q)$(SIZE) -t $(foreach OBJ,$(call objs_list,$<),$(wildcard $(BIN)/$(subst _,?,$(OBJ)).o)) | \
+ sort -g
+
+# Get dependency list for the specified target
+#
+define deps_list
+ $(sort $(foreach OBJ,$(call objs_list,$(1)),$($(OBJ)_DEPS)))
+endef
+$(BIN)/%.deps : $(BIN)/%.tmp
+ $(Q)$(ECHO) $(call deps_list,$<)
+
+# Get unneeded source files for the specified target
+#
+define nodeps_list
+ $(sort $(filter-out $(call deps_list,$(1)),\
+ $(foreach BOBJ,$(BOBJS),\
+ $($(basename $(notdir $(BOBJ)))_DEPS))))
+endef
+$(BIN)/%.nodeps : $(BIN)/%.tmp
+ $(Q)$(ECHO) $(call nodeps_list,$<)
+
+# Get licensing verdict for the specified target
+#
+define unlicensed_deps_list
+ $(shell grep -L FILE_LICENCE $(call deps_list,$(1)))
+endef
+define licence_list
+ $(patsubst __licence_%,%,\
+ $(filter __licence_%,$(shell $(NM) $(1) | cut -d" " -f3)))
+endef
+$(BIN)/%.licence : $(BIN)/%.tmp
+ $(QM)$(ECHO) " [LICENCE] $@"
+ $(Q)$(if $(strip $(call unlicensed_deps_list,$<)),\
+ echo -n "Unable to determine licence because the following " ;\
+ echo "files are missing a licence declaration:" ;\
+ echo $(call unlicensed_deps_list,$<);\
+ exit 1,\
+ $(LICENCE) $(call licence_list,$<))
+
# Extract compression information from intermediate object file
#
$(BIN)/%.zinfo : $(BIN)/%.tmp
@@ -649,6 +776,7 @@ define media_template
@$(ECHO_E) '$$(BIN)/%.$(1) : $$(BIN)/%.$(1).zbin' \
'\n\t$$(QM)$(ECHO) " [FINISH] $$@"' \
'\n\t$$(Q)$$(CP) $$< $$@' \
+ '\n\t$$(Q)$$(PAD_$(1))' \
'\n\t$$(Q)$$(FINALISE_$(1))' \
> $(2)
@@ -702,6 +830,9 @@ endif # defined(BIN)
#
FINALISE_rom = $(MAKEROM) $(MAKEROM_FLAGS) $(TGT_MAKEROM_FLAGS) \
-i$(IDENT) -s 0 $@
+FINALISE_hrom = $(FINALISE_rom)
+FINALISE_xrom = $(MAKEROM) $(MAKEROM_FLAGS) $(TGT_MAKEROM_FLAGS) \
+ -i$(IDENT) -n -s 0 $@
# Some ROMs require specific flags to be passed to makerom.pl
#
@@ -726,16 +857,18 @@ CLEANUP += $(ZBIN)
#
# The EFI image converter
#
+ELF2EFI_CFLAGS := -I$(BINUTILS_DIR)/include -I$(BFD_DIR)/include \
+ -idirafter include -L$(BINUTILS_DIR)/lib -L$(BFD_DIR)/lib \
+ -lbfd -liberty -lz
+
$(ELF2EFI32) : util/elf2efi.c $(MAKEDEPS)
$(QM)$(ECHO) " [HOSTCC] $@"
- $(Q)$(HOST_CC) -DMDE_CPU_IA32 -idirafter include -O2 \
- -o $@ $< -lbfd -liberty
+ $(Q)$(HOST_CC) $(ELF2EFI_CFLAGS) -DMDE_CPU_IA32 -O2 -o $@ $<
CLEANUP += $(ELF2EFI32)
$(ELF2EFI64) : util/elf2efi.c $(MAKEDEPS)
$(QM)$(ECHO) " [HOSTCC] $@"
- $(Q)$(HOST_CC) -DMDE_CPU_X64 -idirafter include -O2 \
- -o $@ $< -lbfd -liberty
+ $(Q)$(HOST_CC) $(ELF2EFI_CFLAGS) -DMDE_CPU_X64 -O2 -o $@ $<
CLEANUP += $(ELF2EFI64)
$(EFIROM) : util/efirom.c $(MAKEDEPS)
@@ -745,6 +878,15 @@ CLEANUP += $(EFIROM)
###############################################################################
#
+# The ICC fixup utility
+#
+$(ICCFIX) : util/iccfix.c $(MAKEDEPS)
+ $(QM)$(ECHO) " [HOSTCC] $@"
+ $(Q)$(HOST_CC) -idirafter include -O2 -o $@ $<
+CLEANUP += $(ICCFIX)
+
+###############################################################################
+#
# Auto-incrementing build serial number. Append "bs" to your list of
# build targets to get a serial number printed at the end of the
# build. Enable -DBUILD_SERIAL in order to see it when the code runs.
@@ -823,20 +965,24 @@ endif # defined(BIN)
ifdef BIN
$(BIN)/doxygen.cfg : doxygen.cfg $(MAKEDEPS)
- $(PERL) -pe 's{\@SRCDIRS\@}{$(SRCDIRS)}; ' \
+ $(Q)$(PERL) -pe 's{\@SRCDIRS\@}{$(SRCDIRS)}; ' \
+ -e 's{\@INCDIRS\@}{$(filter-out .,$(INCDIRS))}; ' \
-e 's{\@BIN\@}{$(BIN)}; ' \
-e 's{\@ARCH\@}{$(ARCH)}; ' \
$< > $@
$(BIN)/doc : $(BIN)/doxygen.cfg
- $(DOXYGEN) $<
+ $(Q)$(DOXYGEN) $<
.PHONY : $(BIN)/doc
-VERYCLEANUP += $(BIN)/doc
-
doc : $(BIN)/doc
+doc-clean :
+ $(Q)$(RM) -r $(BIN)/doc
+
+VERYCLEANUP += $(BIN)/doc
+
docview :
@[ -f $(BIN)/doc/html/index.html ] || $(MAKE) $(BIN)/doc
@if [ -n "$$BROWSER" ] ; then \
diff --git a/gpxe/src/README.pixify b/gpxe/src/README.pixify
deleted file mode 100644
index 9aef25d9..00000000
--- a/gpxe/src/README.pixify
+++ /dev/null
@@ -1,90 +0,0 @@
-This file documents the driver changes needed to support use as part
-of a PXE stack.
-
-PROPER WAY
-==========
-
-1. The probe() routine.
-
-There are three additional fields that need to be filled in the nic
-structure: ioaddr, irqno and irq.
-
- ioaddr is the base I/O address and seems to be for information only;
- no use will be made of this value other than displaying it on the
- screen.
-
- irqno must be the IRQ number for the NIC. For PCI NICs this can
- simply be copied from pci->irq.
-
- irq is a function pointer, like poll and transmit. It must point to
- the driver's irq() function.
-
-2. The poll() routine.
-
-This must take an additional parameter: "int retrieve". Calling
-poll() with retrieve!=0 should function exactly as before. Calling
-poll() with retrieve==0 indicates that poll() should check for the
-presence of a packet to read, but must *not* read the packet. The
-packet will be read by a subsequent call to poll() with retrieve!=0.
-
-The easiest way to implement this is to insert the line
- if ( ! retrieve ) return 1;
-between the "is there a packet ready" and the "fetch packet" parts of
-the existing poll() routine.
-
-Care must be taken that a call to poll() with retrieve==0 does not
-clear the NIC's "packet ready" status indicator, otherwise the
-subsequent call to poll() with retrieve!=0 will fail because it will
-think that there is no packet to read.
-
-poll() should also acknowledge and clear the NIC's "packet received"
-interrupt. It does not need to worry about enabling/disabling
-interrupts; this is taken care of by calls to the driver's irq()
-routine.
-
-Etherboot will forcibly regenerate an interrupt if a packet remains
-pending after all interrupts have been acknowledged. You can
-therefore get away with having poll() just acknolwedge and clear all
-NIC interrupts, without particularly worrying about exactly when this
-should be done.
-
-3. The irq() routine.
-
-This is a new routine, with prototype
- void DRIVER_irq ( struct nic *nic, irq_action_t action );
-"action" takes one of three possible values: ENABLE, DISABLE or FORCE.
-ENABLE and DISABLE mean to enable/disable the NIC's "packet received"
-interrupt. FORCE means that the NIC should be forced to generate a
-fake "packet received" interrupt.
-
-If you are unable to implement FORCE, your NIC will not work when
-being driven via the UNDI interface under heavy network traffic
-conditions. Since Etherboot's UNDI driver (make bin/undi.zpxe) is the
-only program known to use this interface, it probably doesn't really
-matter.
-
-
-QUICK AND DIRTY WAY
-===================
-
-It is possible to use the system timer interrupt (IRQ 0) rather than a
-genuine NIC interrupt. Since there is a constant stream of timer
-interrupts, the net upshot is a whole load of spurious "NIC"
-interrupts that have no effect other than to cause unnecessary PXE API
-calls. It's inefficient but it works.
-
-To achieve this, simply set nic->irqno=0 in probe() and point nic->irq
-to a dummy routine that does nothing. Add the line
- if ( ! retrieve ) return 1;
-at the beginning of poll(), to prevent the packet being read (and
-discarded) when poll() is called with retrieve==0;
-
-
-UNCONVERTED DRIVERS
-===================
-
-Drivers that have not yet been converted should continue to function
-when not used as part of a PXE stack, although there will be a
-harmless compile-time warning about assignment from an incompatible
-pointer type in the probe() function, since the prototype for the
-poll() function is missing the "int retrieve" parameter.
diff --git a/gpxe/src/arch/i386/Makefile b/gpxe/src/arch/i386/Makefile
index 1392bbac..dd8da802 100644
--- a/gpxe/src/arch/i386/Makefile
+++ b/gpxe/src/arch/i386/Makefile
@@ -4,22 +4,33 @@ CFLAGS += -march=i386
# Code size reduction.
#
-CFLAGS += -fstrength-reduce -fomit-frame-pointer
+CFLAGS += -fomit-frame-pointer
+
+# Code size reduction.
+#
+ifeq ($(CCTYPE),gcc)
+CFLAGS += -fstrength-reduce
+endif
# Code size reduction. gcc3 needs a different syntax to gcc2 if you
# want to avoid spurious warnings.
#
+ifeq ($(CCTYPE),gcc)
GCC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion))
GCC_MAJOR := $(firstword $(GCC_VERSION))
ifeq ($(GCC_MAJOR),2)
CFLAGS += -malign-jumps=1 -malign-loops=1 -malign-functions=1
else
CFLAGS += -falign-jumps=1 -falign-loops=1 -falign-functions=1
-endif
+endif # gcc2
+endif # gcc
-# Code size reduction. This is almost always a win. The kernel uses it, too.
+# Code size reduction. This is almost always a win. The kernel uses
+# it, too.
#
+ifeq ($(CCTYPE),gcc)
CFLAGS += -mpreferred-stack-boundary=2
+endif
# Code size reduction. Use regparm for all functions - C functions
# called from assembly (or vice versa) need __asmcall now
@@ -27,7 +38,9 @@ CFLAGS += -mpreferred-stack-boundary=2
CFLAGS += -mregparm=3
# Code size reduction. Use -mrtd (same __asmcall requirements as above)
+ifeq ($(CCTYPE),gcc)
CFLAGS += -mrtd
+endif
# Code size reduction. This is the logical complement to -mregparm=3.
# It doesn't currently buy us anything, but if anything ever tries to
@@ -67,7 +80,9 @@ SRCDIRS += arch/i386/drivers
SRCDIRS += arch/i386/drivers/net
SRCDIRS += arch/i386/interface/pcbios
SRCDIRS += arch/i386/interface/pxe
+SRCDIRS += arch/i386/interface/pxeparent
SRCDIRS += arch/i386/interface/syslinux
+SRCDIRS += arch/i386/hci/commands
# The various xxx_loader.c files are #included into core/loader.c and
# should not be compiled directly.
@@ -76,11 +91,6 @@ NON_AUTO_SRCS += arch/i386/core/aout_loader.c
NON_AUTO_SRCS += arch/i386/core/freebsd_loader.c
NON_AUTO_SRCS += arch/i386/core/wince_loader.c
-# unnrv2b.S is used to generate a 16-bit as well as a 32-bit object.
-#
-OBJS_unnrv2b = unnrv2b unnrv2b16
-CFLAGS_unnrv2b16 = -DCODE16
-
# Include common x86 Makefile
#
MAKEDEPS += arch/x86/Makefile
@@ -101,13 +111,6 @@ NON_AUTO_MEDIA += fd0
$(Q)dd if=$< bs=512 conv=sync of=/dev/fd0
$(Q)sync
-# rule to create padded disk images
-NON_AUTO_MEDIA += pdsk
-%pdsk : %dsk
- $(QM)$(ECHO) " [DSKPAD] $@"
- $(Q)cp $< $@
- $(Q)$(PERL) ./util/dskpad.pl $@
-
# Add NON_AUTO_MEDIA to the media list, so that they show up in the
# output of "make"
#
diff --git a/gpxe/src/arch/i386/Makefile.pcbios b/gpxe/src/arch/i386/Makefile.pcbios
index 64b3dac2..e38fbca0 100644
--- a/gpxe/src/arch/i386/Makefile.pcbios
+++ b/gpxe/src/arch/i386/Makefile.pcbios
@@ -11,21 +11,24 @@ LDFLAGS += -N --no-check-sections
# Media types.
#
MEDIA += rom
+MEDIA += hrom
+MEDIA += xrom
MEDIA += pxe
MEDIA += kpxe
MEDIA += kkpxe
-MEDIA += elf
-MEDIA += elfd
-MEDIA += lmelf
-MEDIA += lmelfd
MEDIA += lkrn
-MEDIA += bImage
MEDIA += dsk
MEDIA += nbi
MEDIA += hd
MEDIA += raw
-MEDIA += com
-MEDIA += exe
+
+# Padding rules
+#
+PAD_rom = $(PADIMG) --blksize=512 --byte=0xff $@
+PAD_hrom = $(PAD_rom)
+PAD_xrom = $(PAD_rom)
+PAD_dsk = $(PADIMG) --blksize=512 $@
+PAD_hd = $(PADIMG) --blksize=32768 $@
# rule to make a non-emulation ISO boot image
NON_AUTO_MEDIA += iso
@@ -39,6 +42,12 @@ NON_AUTO_MEDIA += liso
$(QM)$(ECHO) " [GENLISO] $@"
$(Q)bash util/genliso $@ $<
+# rule to make a syslinux floppy image (mountable, bootable)
+NON_AUTO_MEDIA += sdsk
+%sdsk: %lkrn util/gensdsk
+ $(QM)$(ECHO) " [GENSDSK] $@"
+ $(Q)bash util/gensdsk $@ $<
+
# Special target for building Master Boot Record binary
$(BIN)/mbr.bin : $(BIN)/mbr.o
$(QM)$(ECHO) " [OBJCOPY] $@"
@@ -53,3 +62,9 @@ NON_AUTO_MEDIA += usb
%usb: $(BIN)/usbdisk.bin %hd
$(QM)$(ECHO) " [FINISH] $@"
$(Q)cat $^ > $@
+
+# Padded floppy image (e.g. for iLO)
+NON_AUTO_MEDIA += pdsk
+%pdsk : %dsk
+ $(Q)cp $< $@
+ $(Q)$(PADIMG) --blksize=1474560 $@
diff --git a/gpxe/src/arch/i386/core/basemem_packet.c b/gpxe/src/arch/i386/core/basemem_packet.c
index 64e0bcc1..d487cce3 100644
--- a/gpxe/src/arch/i386/core/basemem_packet.c
+++ b/gpxe/src/arch/i386/core/basemem_packet.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @file
*
diff --git a/gpxe/src/arch/i386/core/etherboot.prefix.lds b/gpxe/src/arch/i386/core/etherboot.prefix.lds
deleted file mode 100644
index 3550a2a3..00000000
--- a/gpxe/src/arch/i386/core/etherboot.prefix.lds
+++ /dev/null
@@ -1,100 +0,0 @@
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-
-ENTRY(_prefix_start)
-SECTIONS {
- /* Prefix */
- .prefix : {
- _verbatim_start = . ;
- _prefix_start = . ;
- *(.prefix)
- . = ALIGN(16);
- _prefix_end = . ;
- } = 0x9090
- _prefix_size = _prefix_end - _prefix_start;
-
- .text.nocompress : {
- *(.prefix.udata)
- } = 0x9090
-
- decompress_to = . ;
- .prefix.zdata : {
- _compressed = . ;
- *(.prefix.zdata)
- _compressed_end = . ;
- }
- _compressed_size = _compressed_end - _compressed;
-
- . = ALIGN(16);
- _verbatim_end = . ;
-
-
- /* Size of the core of etherboot in memory */
- _base_size = _end - _text;
-
- /* _prefix_size is the length of the non-core etherboot prefix */
- _prefix_size = _prefix_end - _prefix_start;
-
- /* _verbatim_size is the actual amount that has to be copied to base memory */
- _verbatim_size = _verbatim_end - _verbatim_start;
-
- /* _image_size is the amount of base memory needed to run */
- _image_size = _base_size + _prefix_size;
-
- /* Standard sizes rounded up to paragraphs */
- _prefix_size_pgh = (_prefix_size + 15) / 16;
- _verbatim_size_pgh = (_verbatim_size + 15) / 16;
- _image_size_pgh = (_image_size + 15) / 16 ;
-
- /* Standard sizes in sectors */
- _prefix_size_sct = (_prefix_size + 511) / 512;
- _verbatim_size_sct = (_verbatim_size + 511) / 512;
- _image_size_sct = (_image_size + 511) / 512;
-
- /* Symbol offsets and sizes for the exe prefix */
- _exe_hdr_size = 32;
- _exe_size = _verbatim_size; /* Should this be - 32 to exclude the header? */
- _exe_size_tail = (_exe_size) % 512;
- _exe_size_pages = ((_exe_size) + 511) / 512;
- _exe_bss_size = ((_image_size - _verbatim_size) + 15) / 16;
- _exe_ss_offset = (_stack_offset + _prefix_size - _exe_hdr_size + 15) / 16 ;
-
- /* This is where we copy the compressed image before decompression.
- * Prepare to decompress in place. The end mark is about 8.25 bytes long,
- * and the worst case symbol is about 16.5 bytes long. Therefore
- * We need to reserve at least 25 bytes of slack here.
- * Currently I reserve 2048 bytes of just slack to be safe :)
- * 2048 bytes easily falls within the BSS (the defualt stack is 4096 bytes)
- * so we really are decompressing in place.
- *
- * Hmm. I missed a trick. In the very worst case (no compression)
- * the encoded data is 9/8 the size as it started out so to be completely
- * safe I need to be 1/8 of the uncompressed code size past the end.
- * This will still fit compfortably into our bss in any conceivable scenario.
- */
- _compressed_copy = _edata + _prefix_size - _compressed_size +
- /* The amount to overflow _edata */
- MAX( ((_edata - _text + 7) / 8) , 2016 ) + 32;
- _assert = ASSERT( ( _compressed_copy - _prefix_size ) < _ebss , "Cannot decompress in place" ) ;
-
- decompress = DEFINED(decompress) ? decompress : 0;
- /DISCARD/ : {
- *(.comment)
- *(.note)
- }
-
- /* Symbols used by the prefixes whose addresses are inconvinient
- * to compute, at runtime in the code.
- */
- image_basemem_size = DEFINED(image_basemem_size)? image_basemem_size : 65536;
- image_basemem = DEFINED(image_basemem)? image_basemem : 65536;
- _prefix_real_to_prot = _real_to_prot + _prefix_size ;
- _prefix_prot_to_real = _prot_to_real + _prefix_size ;
- _prefix_image_basemem_size = image_basemem_size + _prefix_size ;
- _prefix_image_basemem = image_basemem + _prefix_size ;
- _prefix_rm_in_call = _rm_in_call + _prefix_size ;
- _prefix_in_call = _in_call + _prefix_size ;
- _prefix_rom = rom + _prefix_size ;
- _prefix_rm_etherboot_location = rm_etherboot_location + _prefix_size ;
- _prefix_stack_end = _stack_end + _prefix_size ;
-}
diff --git a/gpxe/src/arch/i386/core/pic8259.c b/gpxe/src/arch/i386/core/pic8259.c
index 8a0433dd..1e2d23c5 100644
--- a/gpxe/src/arch/i386/core/pic8259.c
+++ b/gpxe/src/arch/i386/core/pic8259.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/io.h>
#include <pic8259.h>
diff --git a/gpxe/src/arch/i386/core/prefixudata.lds b/gpxe/src/arch/i386/core/prefixudata.lds
deleted file mode 100644
index 1c76128e..00000000
--- a/gpxe/src/arch/i386/core/prefixudata.lds
+++ /dev/null
@@ -1,8 +0,0 @@
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-
-SECTIONS {
- .prefix.udata : {
- *(*)
- }
-}
diff --git a/gpxe/src/arch/i386/core/prefixzdata.lds b/gpxe/src/arch/i386/core/prefixzdata.lds
deleted file mode 100644
index bf6ea977..00000000
--- a/gpxe/src/arch/i386/core/prefixzdata.lds
+++ /dev/null
@@ -1,8 +0,0 @@
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-
-SECTIONS {
- .prefix.zdata : {
- *(*)
- }
-}
diff --git a/gpxe/src/arch/i386/core/rdtsc_timer.c b/gpxe/src/arch/i386/core/rdtsc_timer.c
index 443c8ada..76679173 100644
--- a/gpxe/src/arch/i386/core/rdtsc_timer.c
+++ b/gpxe/src/arch/i386/core/rdtsc_timer.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** @file
*
* RDTSC timer
diff --git a/gpxe/src/arch/i386/core/realmode.c b/gpxe/src/arch/i386/core/realmode.c
deleted file mode 100644
index 9a77bd8a..00000000
--- a/gpxe/src/arch/i386/core/realmode.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Real-mode interface: C portions.
- *
- * Initial version by Michael Brown <mbrown@fensystems.co.uk>, January 2004.
- */
-
-#include "realmode.h"
-
-/*
- * Copy data to/from base memory.
- *
- */
-
-#ifdef KEEP_IT_REAL
-
-void memcpy_to_real ( segoff_t dest, void *src, size_t n ) {
-
-}
-
-void memcpy_from_real ( void *dest, segoff_t src, size_t n ) {
-
-}
-
-#endif /* KEEP_IT_REAL */
diff --git a/gpxe/src/arch/i386/core/relocate.c b/gpxe/src/arch/i386/core/relocate.c
index bdc8498e..44e764fe 100644
--- a/gpxe/src/arch/i386/core/relocate.c
+++ b/gpxe/src/arch/i386/core/relocate.c
@@ -9,6 +9,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/*
* The linker passes in the symbol _max_align, which is the alignment
* that we must preserve, in bytes.
diff --git a/gpxe/src/arch/i386/core/setjmp.S b/gpxe/src/arch/i386/core/setjmp.S
index 59a1b7cb..03727148 100644
--- a/gpxe/src/arch/i386/core/setjmp.S
+++ b/gpxe/src/arch/i386/core/setjmp.S
@@ -1,5 +1,7 @@
/* setjmp and longjmp. Use of these functions is deprecated. */
+FILE_LICENCE ( GPL2_OR_LATER )
+
.text
.arch i386
.code32
diff --git a/gpxe/src/arch/i386/core/stack.S b/gpxe/src/arch/i386/core/stack.S
index da66d239..737ec0ee 100644
--- a/gpxe/src/arch/i386/core/stack.S
+++ b/gpxe/src/arch/i386/core/stack.S
@@ -1,3 +1,5 @@
+FILE_LICENCE ( GPL2_OR_LATER )
+
.arch i386
/****************************************************************************
diff --git a/gpxe/src/arch/i386/core/stack16.S b/gpxe/src/arch/i386/core/stack16.S
index d1251f06..523f0288 100644
--- a/gpxe/src/arch/i386/core/stack16.S
+++ b/gpxe/src/arch/i386/core/stack16.S
@@ -1,3 +1,5 @@
+FILE_LICENCE ( GPL2_OR_LATER )
+
.arch i386
/****************************************************************************
diff --git a/gpxe/src/arch/i386/core/start16.lds b/gpxe/src/arch/i386/core/start16.lds
deleted file mode 100644
index 544fc78f..00000000
--- a/gpxe/src/arch/i386/core/start16.lds
+++ /dev/null
@@ -1,8 +0,0 @@
-/* When linking with an uncompressed image, these symbols are not
- * defined so we provide them here.
- */
-
-__decompressor_uncompressed = 0 ;
-__decompressor__start = 0 ;
-
-INCLUDE arch/i386/core/start16z.lds
diff --git a/gpxe/src/arch/i386/core/start16z.lds b/gpxe/src/arch/i386/core/start16z.lds
deleted file mode 100644
index 711bcf7b..00000000
--- a/gpxe/src/arch/i386/core/start16z.lds
+++ /dev/null
@@ -1,65 +0,0 @@
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-
-/* Linker-generated symbols are prefixed with a double underscore.
- * Decompressor symbols are prefixed with __decompressor_. All other
- * symbols are the same as in the original object file, i.e. the
- * runtime addresses.
- */
-
-ENTRY(_start16)
-
-SECTIONS {
- .text : {
- *(.text)
- }
- .payload : {
- __payload_start = .;
- *(.data)
- __payload_end = .;
- }
-
- /* _payload_size is the size of the binary image appended to
- * start16, in bytes.
- */
- __payload_size = __payload_end - __payload_start ;
-
- /* _size is the size of the runtime image
- * (start32 + the C code), in bytes.
- */
- __size = _end - _start ;
-
- /* _decompressor_size is the size of the decompressor, in
- * bytes. For a non-compressed image, start16.lds sets
- * _decompressor_uncompressed = _decompressor__start = 0.
- */
- __decompressor_size = __decompressor_uncompressed - __decompressor__start ;
-
- /* image__size is the total size of the image, after
- * decompression and including the decompressor if applicable.
- * It is therefore the amount of memory that start16's payload
- * needs in order to execute, in bytes.
- */
- __image_size = __size + __decompressor_size ;
-
- /* Amount to add to runtime symbols to obtain the offset of
- * that symbol within the image.
- */
- __offset_adjust = __decompressor_size - _start ;
-
- /* Calculations for the stack
- */
- __stack_size = _estack - _stack ;
- __offset_stack = _stack + __offset_adjust ;
-
- /* Some symbols will be larger than 16 bits but guaranteed to
- * be multiples of 16. We calculate them in paragraphs and
- * export these symbols which can be used in 16-bit code
- * without risk of overflow.
- */
- __image_size_pgh = ( __image_size / 16 );
- __start_pgh = ( _start / 16 );
- __decompressor_size_pgh = ( __decompressor_size / 16 );
- __offset_stack_pgh = ( __offset_stack / 16 );
-}
-
diff --git a/gpxe/src/arch/i386/core/timer2.c b/gpxe/src/arch/i386/core/timer2.c
index bb589ecc..6e76b2eb 100644
--- a/gpxe/src/arch/i386/core/timer2.c
+++ b/gpxe/src/arch/i386/core/timer2.c
@@ -11,6 +11,8 @@
* your option) any later version.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <gpxe/timer2.h>
#include <gpxe/io.h>
diff --git a/gpxe/src/arch/i386/core/virtaddr.S b/gpxe/src/arch/i386/core/virtaddr.S
index cf6da4f6..aae1e1ed 100644
--- a/gpxe/src/arch/i386/core/virtaddr.S
+++ b/gpxe/src/arch/i386/core/virtaddr.S
@@ -4,6 +4,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER )
+
#include "librm.h"
.arch i386
diff --git a/gpxe/src/arch/i386/core/x86_io.c b/gpxe/src/arch/i386/core/x86_io.c
index 424a96cc..d2c363b9 100644
--- a/gpxe/src/arch/i386/core/x86_io.c
+++ b/gpxe/src/arch/i386/core/x86_io.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/io.h>
#include <gpxe/x86_io.h>
diff --git a/gpxe/src/arch/i386/drivers/net/undi.c b/gpxe/src/arch/i386/drivers/net/undi.c
index 1090cc94..c6e253c0 100644
--- a/gpxe/src/arch/i386/drivers/net/undi.c
+++ b/gpxe/src/arch/i386/drivers/net/undi.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
@@ -135,7 +137,7 @@ static void undipci_remove ( struct pci_device *pci ) {
}
static struct pci_device_id undipci_nics[] = {
-PCI_ROM ( 0xffff, 0xffff, "undipci", "UNDI (PCI)" ),
+PCI_ROM ( 0xffff, 0xffff, "undipci", "UNDI (PCI)", 0 ),
};
struct pci_driver undipci_driver __pci_driver = {
diff --git a/gpxe/src/arch/i386/drivers/net/undiisr.S b/gpxe/src/arch/i386/drivers/net/undiisr.S
index 2b31b414..b27effe1 100644
--- a/gpxe/src/arch/i386/drivers/net/undiisr.S
+++ b/gpxe/src/arch/i386/drivers/net/undiisr.S
@@ -1,3 +1,5 @@
+FILE_LICENCE ( GPL2_OR_LATER )
+
#define PXENV_UNDI_ISR 0x0014
#define PXENV_UNDI_ISR_IN_START 1
#define PXENV_UNDI_ISR_OUT_OURS 0
@@ -29,7 +31,7 @@ undiisr:
movw %ax, %ds
/* Check that we have an UNDI entry point */
- cmpw $0, undinet_entry_point
+ cmpw $0, pxeparent_entry_point
je chain
/* Issue UNDI API call */
@@ -40,7 +42,7 @@ undiisr:
pushw %es
pushw %di
pushw %bx
- lcall *undinet_entry_point
+ lcall *pxeparent_entry_point
cli /* Just in case */
addw $6, %sp
cmpw $PXENV_UNDI_ISR_OUT_OURS, funcflag
diff --git a/gpxe/src/arch/i386/drivers/net/undiload.c b/gpxe/src/arch/i386/drivers/net/undiload.c
index dbd9e7c2..1d4e88d7 100644
--- a/gpxe/src/arch/i386/drivers/net/undiload.c
+++ b/gpxe/src/arch/i386/drivers/net/undiload.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -90,11 +92,10 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
undi_loader_entry = undirom->loader_entry;
__asm__ __volatile__ ( REAL_CODE ( "pushw %%ds\n\t"
"pushw %%ax\n\t"
- "lcall *%c2\n\t"
+ "lcall *undi_loader_entry\n\t"
"addw $4, %%sp\n\t" )
: "=a" ( exit )
- : "a" ( __from_data16 ( &undi_loader ) ),
- "p" ( __from_data16 ( &undi_loader_entry ) )
+ : "a" ( __from_data16 ( &undi_loader ) )
: "ebx", "ecx", "edx", "esi", "edi", "ebp" );
/* UNDI API calls may rudely change the status of A20 and not
diff --git a/gpxe/src/arch/i386/drivers/net/undinet.c b/gpxe/src/arch/i386/drivers/net/undinet.c
index d6db6f7c..83b79e7f 100644
--- a/gpxe/src/arch/i386/drivers/net/undinet.c
+++ b/gpxe/src/arch/i386/drivers/net/undinet.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <string.h>
#include <pxe.h>
#include <realmode.h>
@@ -30,6 +32,7 @@
#include <gpxe/ethernet.h>
#include <undi.h>
#include <undinet.h>
+#include <pxeparent.h>
/** @file
@@ -60,179 +63,8 @@ struct undi_nic {
static void undinet_close ( struct net_device *netdev );
-/*****************************************************************************
- *
- * UNDI API call
- *
- *****************************************************************************
- */
-
-/**
- * Name UNDI API call
- *
- * @v function API call number
- * @ret name API call name
- */
-static inline __attribute__ (( always_inline )) const char *
-undinet_function_name ( unsigned int function ) {
- switch ( function ) {
- case PXENV_START_UNDI:
- return "PXENV_START_UNDI";
- case PXENV_STOP_UNDI:
- return "PXENV_STOP_UNDI";
- case PXENV_UNDI_STARTUP:
- return "PXENV_UNDI_STARTUP";
- case PXENV_UNDI_CLEANUP:
- return "PXENV_UNDI_CLEANUP";
- case PXENV_UNDI_INITIALIZE:
- return "PXENV_UNDI_INITIALIZE";
- case PXENV_UNDI_RESET_ADAPTER:
- return "PXENV_UNDI_RESET_ADAPTER";
- case PXENV_UNDI_SHUTDOWN:
- return "PXENV_UNDI_SHUTDOWN";
- case PXENV_UNDI_OPEN:
- return "PXENV_UNDI_OPEN";
- case PXENV_UNDI_CLOSE:
- return "PXENV_UNDI_CLOSE";
- case PXENV_UNDI_TRANSMIT:
- return "PXENV_UNDI_TRANSMIT";
- case PXENV_UNDI_SET_MCAST_ADDRESS:
- return "PXENV_UNDI_SET_MCAST_ADDRESS";
- case PXENV_UNDI_SET_STATION_ADDRESS:
- return "PXENV_UNDI_SET_STATION_ADDRESS";
- case PXENV_UNDI_SET_PACKET_FILTER:
- return "PXENV_UNDI_SET_PACKET_FILTER";
- case PXENV_UNDI_GET_INFORMATION:
- return "PXENV_UNDI_GET_INFORMATION";
- case PXENV_UNDI_GET_STATISTICS:
- return "PXENV_UNDI_GET_STATISTICS";
- case PXENV_UNDI_CLEAR_STATISTICS:
- return "PXENV_UNDI_CLEAR_STATISTICS";
- case PXENV_UNDI_INITIATE_DIAGS:
- return "PXENV_UNDI_INITIATE_DIAGS";
- case PXENV_UNDI_FORCE_INTERRUPT:
- return "PXENV_UNDI_FORCE_INTERRUPT";
- case PXENV_UNDI_GET_MCAST_ADDRESS:
- return "PXENV_UNDI_GET_MCAST_ADDRESS";
- case PXENV_UNDI_GET_NIC_TYPE:
- return "PXENV_UNDI_GET_NIC_TYPE";
- case PXENV_UNDI_GET_IFACE_INFO:
- return "PXENV_UNDI_GET_IFACE_INFO";
- /*
- * Duplicate case value; this is a bug in the PXE specification.
- *
- * case PXENV_UNDI_GET_STATE:
- * return "PXENV_UNDI_GET_STATE";
- */
- case PXENV_UNDI_ISR:
- return "PXENV_UNDI_ISR";
- default:
- return "UNKNOWN API CALL";
- }
-}
-
-/**
- * UNDI parameter block
- *
- * Used as the paramter block for all UNDI API calls. Resides in base
- * memory.
- */
-static union u_PXENV_ANY __bss16 ( undinet_params );
-#define undinet_params __use_data16 ( undinet_params )
-
-/** UNDI entry point
- *
- * Used as the indirection vector for all UNDI API calls. Resides in
- * base memory.
- */
-SEGOFF16_t __bss16 ( undinet_entry_point );
-#define undinet_entry_point __use_data16 ( undinet_entry_point )
-
-/**
- * Issue UNDI API call
- *
- * @v undinic UNDI NIC
- * @v function API call number
- * @v params UNDI parameter block
- * @v params_len Length of UNDI parameter block
- * @ret rc Return status code
- */
-static int undinet_call ( struct undi_nic *undinic, unsigned int function,
- void *params, size_t params_len ) {
- PXENV_EXIT_t exit;
- int discard_b, discard_D;
- int rc;
-
- /* Copy parameter block and entry point */
- assert ( params_len <= sizeof ( undinet_params ) );
- memcpy ( &undinet_params, params, params_len );
-
- /* Call real-mode entry point. This calling convention will
- * work with both the !PXE and the PXENV+ entry points.
- */
- __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
- "pushw %%di\n\t"
- "pushw %%bx\n\t"
- "lcall *%c3\n\t"
- "addw $6, %%sp\n\t" )
- : "=a" ( exit ), "=b" ( discard_b ),
- "=D" ( discard_D )
- : "p" ( __from_data16 ( &undinet_entry_point )),
- "b" ( function ),
- "D" ( __from_data16 ( &undinet_params ) )
- : "ecx", "edx", "esi", "ebp" );
-
- /* UNDI API calls may rudely change the status of A20 and not
- * bother to restore it afterwards. Intel is known to be
- * guilty of this.
- *
- * Note that we will return to this point even if A20 gets
- * screwed up by the UNDI driver, because Etherboot always
- * resides in an even megabyte of RAM.
- */
- gateA20_set();
-
- /* Determine return status code based on PXENV_EXIT and
- * PXENV_STATUS
- */
- if ( exit == PXENV_EXIT_SUCCESS ) {
- rc = 0;
- } else {
- rc = -undinet_params.Status;
- /* Paranoia; don't return success for the combination
- * of PXENV_EXIT_FAILURE but PXENV_STATUS_SUCCESS
- */
- if ( rc == 0 )
- rc = -EIO;
- }
-
- /* If anything goes wrong, print as much debug information as
- * it's possible to give.
- */
- if ( rc != 0 ) {
- SEGOFF16_t rm_params = {
- .segment = rm_ds,
- .offset = __from_data16 ( &undinet_params ),
- };
-
- DBGC ( undinic, "UNDINIC %p %s failed: %s\n", undinic,
- undinet_function_name ( function ), strerror ( rc ) );
- DBGC ( undinic, "UNDINIC %p parameters at %04x:%04x length "
- "%#02zx, entry point at %04x:%04x\n", undinic,
- rm_params.segment, rm_params.offset, params_len,
- undinet_entry_point.segment,
- undinet_entry_point.offset );
- DBGC ( undinic, "UNDINIC %p parameters provided:\n", undinic );
- DBGC_HDA ( undinic, rm_params, params, params_len );
- DBGC ( undinic, "UNDINIC %p parameters returned:\n", undinic );
- DBGC_HDA ( undinic, rm_params, &undinet_params, params_len );
- }
-
- /* Copy parameter block back */
- memcpy ( params, &undinet_params, params_len );
-
- return rc;
-}
+/** Address of UNDI entry point */
+static SEGOFF16_t undinet_entry;
/*****************************************************************************
*
@@ -335,7 +167,6 @@ static struct s_PXENV_UNDI_TBD __data16 ( undinet_tbd );
*/
static int undinet_transmit ( struct net_device *netdev,
struct io_buffer *iobuf ) {
- struct undi_nic *undinic = netdev->priv;
struct s_PXENV_UNDI_TRANSMIT undi_transmit;
size_t len = iob_len ( iobuf );
int rc;
@@ -368,9 +199,9 @@ static int undinet_transmit ( struct net_device *netdev,
undinet_tbd.Xmit.offset = __from_data16 ( basemem_packet );
/* Issue PXE API call */
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_TRANSMIT,
- &undi_transmit,
- sizeof ( undi_transmit ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_TRANSMIT,
+ &undi_transmit,
+ sizeof ( undi_transmit ) ) ) != 0 )
goto done;
/* Free I/O buffer */
@@ -440,8 +271,9 @@ static void undinet_poll ( struct net_device *netdev ) {
/* Run through the ISR loop */
while ( 1 ) {
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_ISR, &undi_isr,
- sizeof ( undi_isr ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_ISR,
+ &undi_isr,
+ sizeof ( undi_isr ) ) ) != 0 )
break;
switch ( undi_isr.FuncFlag ) {
case PXENV_UNDI_ISR_OUT_TRANSMIT:
@@ -537,8 +369,8 @@ static int undinet_open ( struct net_device *netdev ) {
*/
memcpy ( undi_set_address.StationAddress, netdev->ll_addr,
sizeof ( undi_set_address.StationAddress ) );
- undinet_call ( undinic, PXENV_UNDI_SET_STATION_ADDRESS,
- &undi_set_address, sizeof ( undi_set_address ) );
+ pxeparent_call ( undinet_entry, PXENV_UNDI_SET_STATION_ADDRESS,
+ &undi_set_address, sizeof ( undi_set_address ) );
/* Open NIC. We ask for promiscuous operation, since it's the
* only way to ask for all multicast addresses. On any
@@ -547,8 +379,8 @@ static int undinet_open ( struct net_device *netdev ) {
*/
memset ( &undi_open, 0, sizeof ( undi_open ) );
undi_open.PktFilter = ( FLTR_DIRECTED | FLTR_BRDCST | FLTR_PRMSCS );
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_OPEN, &undi_open,
- sizeof ( undi_open ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_OPEN,
+ &undi_open, sizeof ( undi_open ) ) ) != 0 )
goto err;
DBGC ( undinic, "UNDINIC %p opened\n", undinic );
@@ -573,8 +405,9 @@ static void undinet_close ( struct net_device *netdev ) {
/* Ensure ISR has exited cleanly */
while ( undinic->isr_processing ) {
undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_ISR, &undi_isr,
- sizeof ( undi_isr ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_ISR,
+ &undi_isr,
+ sizeof ( undi_isr ) ) ) != 0 )
break;
switch ( undi_isr.FuncFlag ) {
case PXENV_UNDI_ISR_OUT_TRANSMIT:
@@ -589,8 +422,8 @@ static void undinet_close ( struct net_device *netdev ) {
}
/* Close NIC */
- undinet_call ( undinic, PXENV_UNDI_CLOSE, &undi_close,
- sizeof ( undi_close ) );
+ pxeparent_call ( undinet_entry, PXENV_UNDI_CLOSE,
+ &undi_close, sizeof ( undi_close ) );
/* Disable interrupt and unhook ISR */
disable_irq ( undinic->irq );
@@ -650,7 +483,7 @@ int undinet_probe ( struct undi_device *undi ) {
undi_set_drvdata ( undi, netdev );
netdev->dev = &undi->dev;
memset ( undinic, 0, sizeof ( *undinic ) );
- undinet_entry_point = undi->entry;
+ undinet_entry = undi->entry;
DBGC ( undinic, "UNDINIC %p using UNDI %p\n", undinic, undi );
/* Hook in UNDI stack */
@@ -661,9 +494,9 @@ int undinet_probe ( struct undi_device *undi ) {
start_undi.DX = undi->isapnp_read_port;
start_undi.ES = BIOS_SEG;
start_undi.DI = find_pnp_bios();
- if ( ( rc = undinet_call ( undinic, PXENV_START_UNDI,
- &start_undi,
- sizeof ( start_undi ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_START_UNDI,
+ &start_undi,
+ sizeof ( start_undi ) ) ) != 0 )
goto err_start_undi;
}
undi->flags |= UNDI_FL_STARTED;
@@ -671,24 +504,25 @@ int undinet_probe ( struct undi_device *undi ) {
/* Bring up UNDI stack */
if ( ! ( undi->flags & UNDI_FL_INITIALIZED ) ) {
memset ( &undi_startup, 0, sizeof ( undi_startup ) );
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_STARTUP,
- &undi_startup,
- sizeof ( undi_startup ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_STARTUP,
+ &undi_startup,
+ sizeof ( undi_startup ) ) ) != 0 )
goto err_undi_startup;
memset ( &undi_initialize, 0, sizeof ( undi_initialize ) );
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_INITIALIZE,
- &undi_initialize,
- sizeof ( undi_initialize ))) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry,
+ PXENV_UNDI_INITIALIZE,
+ &undi_initialize,
+ sizeof ( undi_initialize ))) != 0 )
goto err_undi_initialize;
}
undi->flags |= UNDI_FL_INITIALIZED;
/* Get device information */
memset ( &undi_info, 0, sizeof ( undi_info ) );
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_GET_INFORMATION,
- &undi_info, sizeof ( undi_info ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_GET_INFORMATION,
+ &undi_info, sizeof ( undi_info ) ) ) != 0 )
goto err_undi_get_information;
- memcpy ( netdev->ll_addr, undi_info.PermNodeAddress, ETH_ALEN );
+ memcpy ( netdev->hw_addr, undi_info.PermNodeAddress, ETH_ALEN );
undinic->irq = undi_info.IntNumber;
if ( undinic->irq > IRQ_MAX ) {
DBGC ( undinic, "UNDINIC %p invalid IRQ %d\n",
@@ -696,16 +530,17 @@ int undinet_probe ( struct undi_device *undi ) {
goto err_bad_irq;
}
DBGC ( undinic, "UNDINIC %p is %s on IRQ %d\n",
- undinic, eth_ntoa ( netdev->ll_addr ), undinic->irq );
+ undinic, eth_ntoa ( netdev->hw_addr ), undinic->irq );
/* Get interface information */
memset ( &undi_iface, 0, sizeof ( undi_iface ) );
- if ( ( rc = undinet_call ( undinic, PXENV_UNDI_GET_IFACE_INFO,
- &undi_iface,
- sizeof ( undi_iface ) ) ) != 0 )
+ if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_GET_IFACE_INFO,
+ &undi_iface,
+ sizeof ( undi_iface ) ) ) != 0 )
goto err_undi_get_iface_info;
- DBGC ( undinic, "UNDINIC %p has type %s and link speed %d\n",
- undinic, undi_iface.IfaceType, undi_iface.LinkSpeed );
+ DBGC ( undinic, "UNDINIC %p has type %s, speed %d, flags %08x\n",
+ undinic, undi_iface.IfaceType, undi_iface.LinkSpeed,
+ undi_iface.ServiceFlags );
if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot",
sizeof ( undi_iface.IfaceType ) ) == 0 ) {
DBGC ( undinic, "UNDINIC %p Etherboot 5.4 workaround enabled\n",
@@ -730,17 +565,17 @@ int undinet_probe ( struct undi_device *undi ) {
err_undi_initialize:
/* Shut down UNDI stack */
memset ( &undi_shutdown, 0, sizeof ( undi_shutdown ) );
- undinet_call ( undinic, PXENV_UNDI_SHUTDOWN, &undi_shutdown,
- sizeof ( undi_shutdown ) );
+ pxeparent_call ( undinet_entry, PXENV_UNDI_SHUTDOWN, &undi_shutdown,
+ sizeof ( undi_shutdown ) );
memset ( &undi_cleanup, 0, sizeof ( undi_cleanup ) );
- undinet_call ( undinic, PXENV_UNDI_CLEANUP, &undi_cleanup,
- sizeof ( undi_cleanup ) );
+ pxeparent_call ( undinet_entry, PXENV_UNDI_CLEANUP, &undi_cleanup,
+ sizeof ( undi_cleanup ) );
undi->flags &= ~UNDI_FL_INITIALIZED;
err_undi_startup:
/* Unhook UNDI stack */
memset ( &stop_undi, 0, sizeof ( stop_undi ) );
- undinet_call ( undinic, PXENV_STOP_UNDI, &stop_undi,
- sizeof ( stop_undi ) );
+ pxeparent_call ( undinet_entry, PXENV_STOP_UNDI, &stop_undi,
+ sizeof ( stop_undi ) );
undi->flags &= ~UNDI_FL_STARTED;
err_start_undi:
netdev_nullify ( netdev );
@@ -771,22 +606,22 @@ void undinet_remove ( struct undi_device *undi ) {
/* Shut down UNDI stack */
memset ( &undi_shutdown, 0, sizeof ( undi_shutdown ) );
- undinet_call ( undinic, PXENV_UNDI_SHUTDOWN, &undi_shutdown,
- sizeof ( undi_shutdown ) );
+ pxeparent_call ( undinet_entry, PXENV_UNDI_SHUTDOWN,
+ &undi_shutdown, sizeof ( undi_shutdown ) );
memset ( &undi_cleanup, 0, sizeof ( undi_cleanup ) );
- undinet_call ( undinic, PXENV_UNDI_CLEANUP, &undi_cleanup,
- sizeof ( undi_cleanup ) );
+ pxeparent_call ( undinet_entry, PXENV_UNDI_CLEANUP,
+ &undi_cleanup, sizeof ( undi_cleanup ) );
undi->flags &= ~UNDI_FL_INITIALIZED;
/* Unhook UNDI stack */
memset ( &stop_undi, 0, sizeof ( stop_undi ) );
- undinet_call ( undinic, PXENV_STOP_UNDI, &stop_undi,
- sizeof ( stop_undi ) );
+ pxeparent_call ( undinet_entry, PXENV_STOP_UNDI, &stop_undi,
+ sizeof ( stop_undi ) );
undi->flags &= ~UNDI_FL_STARTED;
}
/* Clear entry point */
- memset ( &undinet_entry_point, 0, sizeof ( undinet_entry_point ) );
+ memset ( &undinet_entry, 0, sizeof ( undinet_entry ) );
/* Free network device */
netdev_nullify ( netdev );
diff --git a/gpxe/src/arch/i386/drivers/net/undionly.c b/gpxe/src/arch/i386/drivers/net/undionly.c
index 4cdce677..7dfb5d15 100644
--- a/gpxe/src/arch/i386/drivers/net/undionly.c
+++ b/gpxe/src/arch/i386/drivers/net/undionly.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
diff --git a/gpxe/src/arch/i386/drivers/net/undipreload.c b/gpxe/src/arch/i386/drivers/net/undipreload.c
index e29d150a..a4b2f4ac 100644
--- a/gpxe/src/arch/i386/drivers/net/undipreload.c
+++ b/gpxe/src/arch/i386/drivers/net/undipreload.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <realmode.h>
#include <undipreload.h>
diff --git a/gpxe/src/arch/i386/drivers/net/undirom.c b/gpxe/src/arch/i386/drivers/net/undirom.c
index e5782781..2463d969 100644
--- a/gpxe/src/arch/i386/drivers/net/undirom.c
+++ b/gpxe/src/arch/i386/drivers/net/undirom.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
diff --git a/gpxe/src/arch/i386/firmware/pcbios/basemem.c b/gpxe/src/arch/i386/firmware/pcbios/basemem.c
index b126d2a7..1ba7d1f6 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/basemem.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/basemem.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <realmode.h>
#include <bios.h>
diff --git a/gpxe/src/arch/i386/firmware/pcbios/bios_console.c b/gpxe/src/arch/i386/firmware/pcbios/bios_console.c
index 91363772..1d18e54c 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/bios_console.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/bios_console.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <assert.h>
#include <realmode.h>
#include <console.h>
diff --git a/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S b/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
index decb0835..99ca519b 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
+++ b/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
@@ -15,7 +15,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+
+FILE_LICENCE ( GPL2_OR_LATER )
+
.text
.arch i386
.code16
@@ -235,6 +237,7 @@ get_underlying_e820:
popw %di
incw %bx
movl %edx, %eax
+ clc
ret
2:
/* If the requested region is earlier than the cached region,
diff --git a/gpxe/src/arch/i386/firmware/pcbios/fakee820.c b/gpxe/src/arch/i386/firmware/pcbios/fakee820.c
index 552bf41d..ea116fe5 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/fakee820.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/fakee820.c
@@ -15,6 +15,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <realmode.h>
#include <biosint.h>
diff --git a/gpxe/src/arch/i386/firmware/pcbios/gateA20.c b/gpxe/src/arch/i386/firmware/pcbios/gateA20.c
index 34e3ac52..1a71472d 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/gateA20.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/gateA20.c
@@ -1,3 +1,5 @@
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdio.h>
#include <realmode.h>
#include <bios.h>
diff --git a/gpxe/src/arch/i386/firmware/pcbios/hidemem.c b/gpxe/src/arch/i386/firmware/pcbios/hidemem.c
index 620b62e0..17082c35 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/hidemem.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/hidemem.c
@@ -15,6 +15,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <assert.h>
#include <realmode.h>
#include <biosint.h>
diff --git a/gpxe/src/arch/i386/firmware/pcbios/memmap.c b/gpxe/src/arch/i386/firmware/pcbios/memmap.c
index ff387d93..8a30dbae 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/memmap.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/memmap.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <errno.h>
#include <realmode.h>
diff --git a/gpxe/src/arch/i386/firmware/pcbios/pnpbios.c b/gpxe/src/arch/i386/firmware/pcbios/pnpbios.c
index 420d2ae8..c572914f 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/pnpbios.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/pnpbios.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <string.h>
#include <errno.h>
diff --git a/gpxe/src/arch/i386/hci/commands/pxe_cmd.c b/gpxe/src/arch/i386/hci/commands/pxe_cmd.c
new file mode 100644
index 00000000..b5df2d1b
--- /dev/null
+++ b/gpxe/src/arch/i386/hci/commands/pxe_cmd.c
@@ -0,0 +1,33 @@
+#include <gpxe/netdevice.h>
+#include <gpxe/command.h>
+#include <hci/ifmgmt_cmd.h>
+#include <pxe_call.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+static int startpxe_payload ( struct net_device *netdev ) {
+ if ( netdev->state & NETDEV_OPEN )
+ pxe_activate ( netdev );
+ return 0;
+}
+
+static int startpxe_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, startpxe_payload,
+ "Activate PXE on" );
+}
+
+static int stoppxe_exec ( int argc __unused, char **argv __unused ) {
+ pxe_deactivate();
+ return 0;
+}
+
+struct command pxe_commands[] __command = {
+ {
+ .name = "startpxe",
+ .exec = startpxe_exec,
+ },
+ {
+ .name = "stoppxe",
+ .exec = stoppxe_exec,
+ },
+};
diff --git a/gpxe/src/arch/i386/image/bootsector.c b/gpxe/src/arch/i386/image/bootsector.c
index 0f297a26..f96cf201 100644
--- a/gpxe/src/arch/i386/image/bootsector.c
+++ b/gpxe/src/arch/i386/image/bootsector.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @file
*
diff --git a/gpxe/src/arch/i386/image/bzimage.c b/gpxe/src/arch/i386/image/bzimage.c
index 47d46ca4..19450990 100644
--- a/gpxe/src/arch/i386/image/bzimage.c
+++ b/gpxe/src/arch/i386/image/bzimage.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @file
*
@@ -42,9 +44,11 @@ FEATURE ( FEATURE_IMAGE, "bzImage", DHCP_EB_FEATURE_BZIMAGE, 1 );
struct image_type bzimage_image_type __image_type ( PROBE_NORMAL );
/**
- * bzImage load context
+ * bzImage context
*/
-struct bzimage_load_context {
+struct bzimage_context {
+ /** Boot protocol version */
+ unsigned int version;
/** Real-mode kernel portion load segment address */
unsigned int rm_kernel_seg;
/** Real-mode kernel portion load address */
@@ -55,28 +59,14 @@ struct bzimage_load_context {
size_t rm_heap;
/** Command line (offset from rm_kernel) */
size_t rm_cmdline;
+ /** Command line maximum length */
+ size_t cmdline_size;
/** Real-mode kernel portion total memory size */
size_t rm_memsz;
/** Non-real-mode kernel portion load address */
userptr_t pm_kernel;
/** Non-real-mode kernel portion file and memory size */
size_t pm_sz;
-};
-
-/**
- * bzImage execution context
- */
-struct bzimage_exec_context {
- /** Real-mode kernel portion load segment address */
- unsigned int rm_kernel_seg;
- /** Real-mode kernel portion load address */
- userptr_t rm_kernel;
- /** Real-mode heap top (offset from rm_kernel) */
- size_t rm_heap;
- /** Command line (offset from rm_kernel) */
- size_t rm_cmdline;
- /** Command line maximum length */
- size_t cmdline_size;
/** Video mode */
unsigned int vid_mode;
/** Memory limit */
@@ -85,18 +75,178 @@ struct bzimage_exec_context {
physaddr_t ramdisk_image;
/** Initrd size */
physaddr_t ramdisk_size;
+
+ /** Command line magic block */
+ struct bzimage_cmdline cmdline_magic;
+ /** bzImage header */
+ struct bzimage_header bzhdr;
};
/**
+ * Parse bzImage header
+ *
+ * @v image bzImage file
+ * @v bzimg bzImage context
+ * @v src bzImage to parse
+ * @ret rc Return status code
+ */
+static int bzimage_parse_header ( struct image *image,
+ struct bzimage_context *bzimg,
+ userptr_t src ) {
+ unsigned int syssize;
+ int is_bzimage;
+
+ /* Sanity check */
+ if ( image->len < ( BZI_HDR_OFFSET + sizeof ( bzimg->bzhdr ) ) ) {
+ DBGC ( image, "bzImage %p too short for kernel header\n",
+ image );
+ return -ENOEXEC;
+ }
+
+ /* Read in header structures */
+ memset ( bzimg, 0, sizeof ( *bzimg ) );
+ copy_from_user ( &bzimg->cmdline_magic, src, BZI_CMDLINE_OFFSET,
+ sizeof ( bzimg->cmdline_magic ) );
+ copy_from_user ( &bzimg->bzhdr, src, BZI_HDR_OFFSET,
+ sizeof ( bzimg->bzhdr ) );
+
+ /* Calculate size of real-mode portion */
+ bzimg->rm_filesz =
+ ( ( bzimg->bzhdr.setup_sects ? bzimg->bzhdr.setup_sects : 4 ) + 1 ) << 9;
+ if ( bzimg->rm_filesz > image->len ) {
+ DBGC ( image, "bzImage %p too short for %zd byte of setup\n",
+ image, bzimg->rm_filesz );
+ return -ENOEXEC;
+ }
+ bzimg->rm_memsz = BZI_ASSUMED_RM_SIZE;
+
+ /* Calculate size of protected-mode portion */
+ bzimg->pm_sz = ( image->len - bzimg->rm_filesz );
+ syssize = ( ( bzimg->pm_sz + 15 ) / 16 );
+
+ /* Check for signatures and determine version */
+ if ( bzimg->bzhdr.boot_flag != BZI_BOOT_FLAG ) {
+ DBGC ( image, "bzImage %p missing 55AA signature\n", image );
+ return -ENOEXEC;
+ }
+ if ( bzimg->bzhdr.header == BZI_SIGNATURE ) {
+ /* 2.00+ */
+ bzimg->version = bzimg->bzhdr.version;
+ } else {
+ /* Pre-2.00. Check that the syssize field is correct,
+ * as a guard against accepting arbitrary binary data,
+ * since the 55AA check is pretty lax. Note that the
+ * syssize field is unreliable for protocols between
+ * 2.00 and 2.03 inclusive, so we should not always
+ * check this field.
+ */
+ bzimg->version = 0x0100;
+ if ( bzimg->bzhdr.syssize != syssize ) {
+ DBGC ( image, "bzImage %p bad syssize %x (expected "
+ "%x)\n", image, bzimg->bzhdr.syssize, syssize );
+ return -ENOEXEC;
+ }
+ }
+
+ /* Determine image type */
+ is_bzimage = ( ( bzimg->version >= 0x0200 ) ?
+ ( bzimg->bzhdr.loadflags & BZI_LOAD_HIGH ) : 0 );
+
+ /* Calculate load address of real-mode portion */
+ bzimg->rm_kernel_seg = ( is_bzimage ? 0x1000 : 0x9000 );
+ bzimg->rm_kernel = real_to_user ( bzimg->rm_kernel_seg, 0 );
+
+ /* Allow space for the stack and heap */
+ bzimg->rm_memsz += BZI_STACK_SIZE;
+ bzimg->rm_heap = bzimg->rm_memsz;
+
+ /* Allow space for the command line */
+ bzimg->rm_cmdline = bzimg->rm_memsz;
+ bzimg->rm_memsz += BZI_CMDLINE_SIZE;
+
+ /* Calculate load address of protected-mode portion */
+ bzimg->pm_kernel = phys_to_user ( is_bzimage ? BZI_LOAD_HIGH_ADDR
+ : BZI_LOAD_LOW_ADDR );
+
+ /* Extract video mode */
+ bzimg->vid_mode = bzimg->bzhdr.vid_mode;
+
+ /* Extract memory limit */
+ bzimg->mem_limit = ( ( bzimg->version >= 0x0203 ) ?
+ bzimg->bzhdr.initrd_addr_max : BZI_INITRD_MAX );
+
+ /* Extract command line size */
+ bzimg->cmdline_size = ( ( bzimg->version >= 0x0206 ) ?
+ bzimg->bzhdr.cmdline_size : BZI_CMDLINE_SIZE );
+
+ DBGC ( image, "bzImage %p version %04x RM %#lx+%#zx PM %#lx+%#zx "
+ "cmdlen %zd\n", image, bzimg->version,
+ user_to_phys ( bzimg->rm_kernel, 0 ), bzimg->rm_filesz,
+ user_to_phys ( bzimg->pm_kernel, 0 ), bzimg->pm_sz,
+ bzimg->cmdline_size );
+
+ return 0;
+}
+
+/**
+ * Update bzImage header in loaded kernel
+ *
+ * @v image bzImage file
+ * @v bzimg bzImage context
+ * @v dst bzImage to update
+ */
+static void bzimage_update_header ( struct image *image,
+ struct bzimage_context *bzimg,
+ userptr_t dst ) {
+
+ /* Set loader type */
+ if ( bzimg->version >= 0x0200 )
+ bzimg->bzhdr.type_of_loader = BZI_LOADER_TYPE_GPXE;
+
+ /* Set heap end pointer */
+ if ( bzimg->version >= 0x0201 ) {
+ bzimg->bzhdr.heap_end_ptr = ( bzimg->rm_heap - 0x200 );
+ bzimg->bzhdr.loadflags |= BZI_CAN_USE_HEAP;
+ }
+
+ /* Set command line */
+ if ( bzimg->version >= 0x0202 ) {
+ bzimg->bzhdr.cmd_line_ptr = user_to_phys ( bzimg->rm_kernel,
+ bzimg->rm_cmdline );
+ } else {
+ bzimg->cmdline_magic.magic = BZI_CMDLINE_MAGIC;
+ bzimg->cmdline_magic.offset = bzimg->rm_cmdline;
+ bzimg->bzhdr.setup_move_size = bzimg->rm_memsz;
+ }
+
+ /* Set video mode */
+ bzimg->bzhdr.vid_mode = bzimg->vid_mode;
+
+ /* Set initrd address */
+ if ( bzimg->version >= 0x0200 ) {
+ bzimg->bzhdr.ramdisk_image = bzimg->ramdisk_image;
+ bzimg->bzhdr.ramdisk_size = bzimg->ramdisk_size;
+ }
+
+ /* Write out header structures */
+ copy_to_user ( dst, BZI_CMDLINE_OFFSET, &bzimg->cmdline_magic,
+ sizeof ( bzimg->cmdline_magic ) );
+ copy_to_user ( dst, BZI_HDR_OFFSET, &bzimg->bzhdr,
+ sizeof ( bzimg->bzhdr ) );
+
+ DBGC ( image, "bzImage %p vidmode %d\n", image, bzimg->vid_mode );
+}
+
+/**
* Parse kernel command line for bootloader parameters
*
* @v image bzImage file
- * @v exec_ctx Execution context
+ * @v bzimg bzImage context
* @v cmdline Kernel command line
* @ret rc Return status code
*/
static int bzimage_parse_cmdline ( struct image *image,
- struct bzimage_exec_context *exec_ctx,
+ struct bzimage_context *bzimg,
const char *cmdline ) {
char *vga;
char *mem;
@@ -105,13 +255,13 @@ static int bzimage_parse_cmdline ( struct image *image,
if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
vga += 4;
if ( strcmp ( vga, "normal" ) == 0 ) {
- exec_ctx->vid_mode = BZI_VID_MODE_NORMAL;
+ bzimg->vid_mode = BZI_VID_MODE_NORMAL;
} else if ( strcmp ( vga, "ext" ) == 0 ) {
- exec_ctx->vid_mode = BZI_VID_MODE_EXT;
+ bzimg->vid_mode = BZI_VID_MODE_EXT;
} else if ( strcmp ( vga, "ask" ) == 0 ) {
- exec_ctx->vid_mode = BZI_VID_MODE_ASK;
+ bzimg->vid_mode = BZI_VID_MODE_ASK;
} else {
- exec_ctx->vid_mode = strtoul ( vga, &vga, 0 );
+ bzimg->vid_mode = strtoul ( vga, &vga, 0 );
if ( *vga && ( *vga != ' ' ) ) {
DBGC ( image, "bzImage %p strange \"vga=\""
"terminator '%c'\n", image, *vga );
@@ -122,17 +272,17 @@ static int bzimage_parse_cmdline ( struct image *image,
/* Look for "mem=" */
if ( ( mem = strstr ( cmdline, "mem=" ) ) ) {
mem += 4;
- exec_ctx->mem_limit = strtoul ( mem, &mem, 0 );
+ bzimg->mem_limit = strtoul ( mem, &mem, 0 );
switch ( *mem ) {
case 'G':
case 'g':
- exec_ctx->mem_limit <<= 10;
+ bzimg->mem_limit <<= 10;
case 'M':
case 'm':
- exec_ctx->mem_limit <<= 10;
+ bzimg->mem_limit <<= 10;
case 'K':
case 'k':
- exec_ctx->mem_limit <<= 10;
+ bzimg->mem_limit <<= 10;
break;
case '\0':
case ' ':
@@ -142,7 +292,7 @@ static int bzimage_parse_cmdline ( struct image *image,
"terminator '%c'\n", image, *mem );
break;
}
- exec_ctx->mem_limit -= 1;
+ bzimg->mem_limit -= 1;
}
return 0;
@@ -152,20 +302,20 @@ static int bzimage_parse_cmdline ( struct image *image,
* Set command line
*
* @v image bzImage image
- * @v exec_ctx Execution context
+ * @v bzimg bzImage context
* @v cmdline Kernel command line
* @ret rc Return status code
*/
static int bzimage_set_cmdline ( struct image *image,
- struct bzimage_exec_context *exec_ctx,
+ struct bzimage_context *bzimg,
const char *cmdline ) {
size_t cmdline_len;
/* Copy command line down to real-mode portion */
cmdline_len = ( strlen ( cmdline ) + 1 );
- if ( cmdline_len > exec_ctx->cmdline_size )
- cmdline_len = exec_ctx->cmdline_size;
- copy_to_user ( exec_ctx->rm_kernel, exec_ctx->rm_cmdline,
+ if ( cmdline_len > bzimg->cmdline_size )
+ cmdline_len = bzimg->cmdline_size;
+ copy_to_user ( bzimg->rm_kernel, bzimg->rm_cmdline,
cmdline, cmdline_len );
DBGC ( image, "bzImage %p command line \"%s\"\n", image, cmdline );
@@ -217,14 +367,16 @@ static size_t bzimage_load_initrd ( struct image *image,
}
/* Copy in initrd image body */
+ if ( address )
+ memcpy_user ( address, offset, initrd->data, 0, initrd->len );
+ offset += initrd->len;
if ( address ) {
DBGC ( image, "bzImage %p has initrd %p at [%lx,%lx)\n",
- image, initrd, address, ( address + offset ) );
- memcpy_user ( address, offset, initrd->data, 0,
- initrd->len );
+ image, initrd, user_to_phys ( address, 0 ),
+ user_to_phys ( address, offset ) );
}
- offset += initrd->len;
+ /* Round up to 4-byte boundary */
offset = ( ( offset + 0x03 ) & ~0x03 );
return offset;
}
@@ -233,20 +385,19 @@ static size_t bzimage_load_initrd ( struct image *image,
* Load initrds, if any
*
* @v image bzImage image
- * @v exec_ctx Execution context
+ * @v bzimg bzImage context
* @ret rc Return status code
*/
static int bzimage_load_initrds ( struct image *image,
- struct bzimage_exec_context *exec_ctx ) {
+ struct bzimage_context *bzimg ) {
struct image *initrd;
size_t total_len = 0;
physaddr_t address;
int rc;
/* Add up length of all initrd images */
- for_each_image ( initrd ) {
+ for_each_image ( initrd )
total_len += bzimage_load_initrd ( image, initrd, UNULL );
- }
/* Give up if no initrd images found */
if ( ! total_len )
@@ -268,7 +419,7 @@ static int bzimage_load_initrds ( struct image *image,
return -ENOBUFS;
}
/* Check that we are within the kernel's range */
- if ( ( address + total_len - 1 ) > exec_ctx->mem_limit )
+ if ( ( address + total_len - 1 ) > bzimg->mem_limit )
continue;
/* Prepare and verify segment */
if ( ( rc = prep_segment ( phys_to_user ( address ), 0,
@@ -279,8 +430,8 @@ static int bzimage_load_initrds ( struct image *image,
}
/* Record initrd location */
- exec_ctx->ramdisk_image = address;
- exec_ctx->ramdisk_size = total_len;
+ bzimg->ramdisk_image = address;
+ bzimg->ramdisk_size = total_len;
/* Construct initrd */
DBGC ( image, "bzImage %p constructing initrd at [%lx,%lx)\n",
@@ -300,60 +451,37 @@ static int bzimage_load_initrds ( struct image *image,
* @ret rc Return status code
*/
static int bzimage_exec ( struct image *image ) {
- struct bzimage_exec_context exec_ctx;
- struct bzimage_header bzhdr;
+ struct bzimage_context bzimg;
const char *cmdline = ( image->cmdline ? image->cmdline : "" );
int rc;
- /* Initialise context */
- memset ( &exec_ctx, 0, sizeof ( exec_ctx ) );
-
- /* Retrieve kernel header */
- exec_ctx.rm_kernel_seg = image->priv.ul;
- exec_ctx.rm_kernel = real_to_user ( exec_ctx.rm_kernel_seg, 0 );
- copy_from_user ( &bzhdr, exec_ctx.rm_kernel, BZI_HDR_OFFSET,
- sizeof ( bzhdr ) );
- exec_ctx.rm_cmdline = exec_ctx.rm_heap =
- ( bzhdr.heap_end_ptr + 0x200 );
- exec_ctx.vid_mode = bzhdr.vid_mode;
- if ( bzhdr.version >= 0x0203 ) {
- exec_ctx.mem_limit = bzhdr.initrd_addr_max;
- } else {
- exec_ctx.mem_limit = BZI_INITRD_MAX;
- }
- if ( bzhdr.version >= 0x0206 ) {
- exec_ctx.cmdline_size = bzhdr.cmdline_size;
- } else {
- exec_ctx.cmdline_size = BZI_CMDLINE_SIZE;
- }
- DBG ( "cmdline_size = %zd\n", exec_ctx.cmdline_size );
+ /* Read and parse header from loaded kernel */
+ if ( ( rc = bzimage_parse_header ( image, &bzimg,
+ image->priv.user ) ) != 0 )
+ return rc;
+ assert ( bzimg.rm_kernel == image->priv.user );
/* Parse command line for bootloader parameters */
- if ( ( rc = bzimage_parse_cmdline ( image, &exec_ctx, cmdline ) ) != 0)
+ if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0)
return rc;
/* Store command line */
- if ( ( rc = bzimage_set_cmdline ( image, &exec_ctx, cmdline ) ) != 0 )
+ if ( ( rc = bzimage_set_cmdline ( image, &bzimg, cmdline ) ) != 0 )
return rc;
/* Load any initrds */
- if ( ( rc = bzimage_load_initrds ( image, &exec_ctx ) ) != 0 )
+ if ( ( rc = bzimage_load_initrds ( image, &bzimg ) ) != 0 )
return rc;
- /* Update and store kernel header */
- bzhdr.vid_mode = exec_ctx.vid_mode;
- bzhdr.ramdisk_image = exec_ctx.ramdisk_image;
- bzhdr.ramdisk_size = exec_ctx.ramdisk_size;
- copy_to_user ( exec_ctx.rm_kernel, BZI_HDR_OFFSET, &bzhdr,
- sizeof ( bzhdr ) );
+ /* Update kernel header */
+ bzimage_update_header ( image, &bzimg, bzimg.rm_kernel );
/* Prepare for exiting */
shutdown ( SHUTDOWN_BOOT );
DBGC ( image, "bzImage %p jumping to RM kernel at %04x:0000 "
- "(stack %04x:%04zx)\n", image,
- ( exec_ctx.rm_kernel_seg + 0x20 ),
- exec_ctx.rm_kernel_seg, exec_ctx.rm_heap );
+ "(stack %04x:%04zx)\n", image, ( bzimg.rm_kernel_seg + 0x20 ),
+ bzimg.rm_kernel_seg, bzimg.rm_heap );
/* Jump to the kernel */
__asm__ __volatile__ ( REAL_CODE ( "movw %w0, %%ds\n\t"
@@ -365,9 +493,9 @@ static int bzimage_exec ( struct image *image ) {
"pushw %w2\n\t"
"pushw $0\n\t"
"lret\n\t" )
- : : "r" ( exec_ctx.rm_kernel_seg ),
- "r" ( exec_ctx.rm_heap ),
- "r" ( exec_ctx.rm_kernel_seg + 0x20 ) );
+ : : "r" ( bzimg.rm_kernel_seg ),
+ "r" ( bzimg.rm_heap ),
+ "r" ( bzimg.rm_kernel_seg + 0x20 ) );
/* There is no way for the image to return, since we provide
* no return address.
@@ -378,192 +506,49 @@ static int bzimage_exec ( struct image *image ) {
}
/**
- * Load and parse bzImage header
- *
- * @v image bzImage file
- * @v load_ctx Load context
- * @v bzhdr Buffer for bzImage header
- * @ret rc Return status code
- */
-static int bzimage_load_header ( struct image *image,
- struct bzimage_load_context *load_ctx,
- struct bzimage_header *bzhdr ) {
-
- /* Sanity check */
- if ( image->len < ( BZI_HDR_OFFSET + sizeof ( *bzhdr ) ) ) {
- DBGC ( image, "bzImage %p too short for kernel header\n",
- image );
- return -ENOEXEC;
- }
-
- /* Read and verify header */
- copy_from_user ( bzhdr, image->data, BZI_HDR_OFFSET,
- sizeof ( *bzhdr ) );
- if ( bzhdr->header != BZI_SIGNATURE ) {
- DBGC ( image, "bzImage %p bad signature %08x\n",
- image, bzhdr->header );
- return -ENOEXEC;
- }
-
- /* We don't support ancient kernels */
- if ( bzhdr->version < 0x0200 ) {
- DBGC ( image, "bzImage %p version %04x not supported\n",
- image, bzhdr->version );
- return -ENOTSUP;
- }
-
- /* Calculate load address and size of real-mode portion */
- load_ctx->rm_kernel_seg = ( ( bzhdr->loadflags & BZI_LOAD_HIGH ) ?
- 0x1000 : /* 1000:0000 (bzImage) */
- 0x9000 ); /* 9000:0000 (zImage) */
- load_ctx->rm_kernel = real_to_user ( load_ctx->rm_kernel_seg, 0 );
- load_ctx->rm_filesz =
- ( ( bzhdr->setup_sects ? bzhdr->setup_sects : 4 ) + 1 ) << 9;
- load_ctx->rm_memsz = BZI_ASSUMED_RM_SIZE;
- if ( load_ctx->rm_filesz > image->len ) {
- DBGC ( image, "bzImage %p too short for %zd byte of setup\n",
- image, load_ctx->rm_filesz );
- return -ENOEXEC;
- }
-
- /* Calculate load address and size of non-real-mode portion */
- load_ctx->pm_kernel = ( ( bzhdr->loadflags & BZI_LOAD_HIGH ) ?
- phys_to_user ( BZI_LOAD_HIGH_ADDR ) :
- phys_to_user ( BZI_LOAD_LOW_ADDR ) );
- load_ctx->pm_sz = ( image->len - load_ctx->rm_filesz );
-
- DBGC ( image, "bzImage %p version %04x RM %#zx bytes PM %#zx bytes\n",
- image, bzhdr->version, load_ctx->rm_filesz, load_ctx->pm_sz );
- return 0;
-}
-
-/**
- * Load real-mode portion of bzImage
+ * Load bzImage image into memory
*
* @v image bzImage file
- * @v load_ctx Load context
* @ret rc Return status code
*/
-static int bzimage_load_real ( struct image *image,
- struct bzimage_load_context *load_ctx ) {
+int bzimage_load ( struct image *image ) {
+ struct bzimage_context bzimg;
int rc;
- /* Allow space for the stack and heap */
- load_ctx->rm_memsz += BZI_STACK_SIZE;
- load_ctx->rm_heap = load_ctx->rm_memsz;
+ /* Read and parse header from image */
+ if ( ( rc = bzimage_parse_header ( image, &bzimg,
+ image->data ) ) != 0 )
+ return rc;
- /* Allow space for the command line */
- load_ctx->rm_cmdline = load_ctx->rm_memsz;
- load_ctx->rm_memsz += BZI_CMDLINE_SIZE;
+ /* This is a bzImage image, valid or otherwise */
+ if ( ! image->type )
+ image->type = &bzimage_image_type;
- /* Prepare, verify, and load the real-mode segment */
- if ( ( rc = prep_segment ( load_ctx->rm_kernel, load_ctx->rm_filesz,
- load_ctx->rm_memsz ) ) != 0 ) {
+ /* Prepare segments */
+ if ( ( rc = prep_segment ( bzimg.rm_kernel, bzimg.rm_filesz,
+ bzimg.rm_memsz ) ) != 0 ) {
DBGC ( image, "bzImage %p could not prepare RM segment: %s\n",
image, strerror ( rc ) );
return rc;
}
- memcpy_user ( load_ctx->rm_kernel, 0, image->data, 0,
- load_ctx->rm_filesz );
-
- return 0;
-}
-
-/**
- * Load non-real-mode portion of bzImage
- *
- * @v image bzImage file
- * @v load_ctx Load context
- * @ret rc Return status code
- */
-static int bzimage_load_non_real ( struct image *image,
- struct bzimage_load_context *load_ctx ) {
- int rc;
-
- /* Prepare, verify and load the non-real-mode segment */
- if ( ( rc = prep_segment ( load_ctx->pm_kernel, load_ctx->pm_sz,
- load_ctx->pm_sz ) ) != 0 ) {
+ if ( ( rc = prep_segment ( bzimg.pm_kernel, bzimg.pm_sz,
+ bzimg.pm_sz ) ) != 0 ) {
DBGC ( image, "bzImage %p could not prepare PM segment: %s\n",
image, strerror ( rc ) );
return rc;
}
- memcpy_user ( load_ctx->pm_kernel, 0, image->data, load_ctx->rm_filesz,
- load_ctx->pm_sz );
-
- return 0;
-}
-
-/**
- * Update and store bzImage header
- *
- * @v image bzImage file
- * @v load_ctx Load context
- * @v bzhdr Original bzImage header
- * @ret rc Return status code
- */
-static int bzimage_write_header ( struct image *image __unused,
- struct bzimage_load_context *load_ctx,
- struct bzimage_header *bzhdr ) {
- struct bzimage_cmdline cmdline;
-
- /* Update the header and copy it into the loaded kernel */
- bzhdr->type_of_loader = BZI_LOADER_TYPE_GPXE;
- if ( bzhdr->version >= 0x0201 ) {
- bzhdr->heap_end_ptr = ( load_ctx->rm_heap - 0x200 );
- bzhdr->loadflags |= BZI_CAN_USE_HEAP;
- }
- if ( bzhdr->version >= 0x0202 ) {
- bzhdr->cmd_line_ptr = user_to_phys ( load_ctx->rm_kernel,
- load_ctx->rm_cmdline );
- } else {
- cmdline.magic = BZI_CMDLINE_MAGIC;
- cmdline.offset = load_ctx->rm_cmdline;
- copy_to_user ( load_ctx->rm_kernel, BZI_CMDLINE_OFFSET,
- &cmdline, sizeof ( cmdline ) );
- bzhdr->setup_move_size = load_ctx->rm_memsz;
- }
- copy_to_user ( load_ctx->rm_kernel, BZI_HDR_OFFSET,
- bzhdr, sizeof ( *bzhdr ) );
-
- return 0;
-}
-
-/**
- * Load bzImage image into memory
- *
- * @v image bzImage file
- * @ret rc Return status code
- */
-int bzimage_load ( struct image *image ) {
- struct bzimage_load_context load_ctx;
- struct bzimage_header bzhdr;
- int rc;
-
- /* Initialise context */
- memset ( &load_ctx, 0, sizeof ( load_ctx ) );
- /* Load and verify header */
- if ( ( rc = bzimage_load_header ( image, &load_ctx, &bzhdr ) ) != 0 )
- return rc;
-
- /* This is a bzImage image, valid or otherwise */
- if ( ! image->type )
- image->type = &bzimage_image_type;
-
- /* Load real-mode portion */
- if ( ( rc = bzimage_load_real ( image, &load_ctx ) ) != 0 )
- return rc;
-
- /* Load non-real-mode portion */
- if ( ( rc = bzimage_load_non_real ( image, &load_ctx ) ) != 0 )
- return rc;
+ /* Load segments */
+ memcpy_user ( bzimg.rm_kernel, 0, image->data,
+ 0, bzimg.rm_filesz );
+ memcpy_user ( bzimg.pm_kernel, 0, image->data,
+ bzimg.rm_filesz, bzimg.pm_sz );
/* Update and write out header */
- if ( ( rc = bzimage_write_header ( image, &load_ctx, &bzhdr ) ) != 0 )
- return rc;
+ bzimage_update_header ( image, &bzimg, bzimg.rm_kernel );
/* Record real-mode segment in image private data field */
- image->priv.ul = load_ctx.rm_kernel_seg;
+ image->priv.user = bzimg.rm_kernel;
return 0;
}
diff --git a/gpxe/src/arch/i386/image/com32.c b/gpxe/src/arch/i386/image/com32.c
index d1b9a59f..6ab347c1 100644
--- a/gpxe/src/arch/i386/image/com32.c
+++ b/gpxe/src/arch/i386/image/com32.c
@@ -23,6 +23,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
diff --git a/gpxe/src/arch/i386/image/comboot.c b/gpxe/src/arch/i386/image/comboot.c
index 40e32185..a00b2b95 100644
--- a/gpxe/src/arch/i386/image/comboot.c
+++ b/gpxe/src/arch/i386/image/comboot.c
@@ -23,6 +23,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
diff --git a/gpxe/src/arch/i386/image/elfboot.c b/gpxe/src/arch/i386/image/elfboot.c
index c8daf72b..a41040e8 100644
--- a/gpxe/src/arch/i386/image/elfboot.c
+++ b/gpxe/src/arch/i386/image/elfboot.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <errno.h>
#include <elf.h>
#include <gpxe/image.h>
diff --git a/gpxe/src/arch/i386/image/eltorito.c b/gpxe/src/arch/i386/image/eltorito.c
index 9d573106..53eb2c02 100644
--- a/gpxe/src/arch/i386/image/eltorito.c
+++ b/gpxe/src/arch/i386/image/eltorito.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @file
*
diff --git a/gpxe/src/arch/i386/image/multiboot.c b/gpxe/src/arch/i386/image/multiboot.c
index 52bb10f6..5b620956 100644
--- a/gpxe/src/arch/i386/image/multiboot.c
+++ b/gpxe/src/arch/i386/image/multiboot.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @file
*
@@ -139,10 +141,11 @@ static void multiboot_build_memmap ( struct image *image,
/**
* Add command line in base memory
*
+ * @v imgname Image name
* @v cmdline Command line
* @ret physaddr Physical address of command line
*/
-physaddr_t multiboot_add_cmdline ( const char *cmdline ) {
+physaddr_t multiboot_add_cmdline ( const char *imgname, const char *cmdline ) {
char *mb_cmdline;
if ( ! cmdline )
@@ -153,7 +156,7 @@ physaddr_t multiboot_add_cmdline ( const char *cmdline ) {
mb_cmdline_offset +=
( snprintf ( mb_cmdline,
( sizeof ( mb_cmdlines ) - mb_cmdline_offset ),
- "%s", cmdline ) + 1 );
+ "%s %s", imgname, cmdline ) + 1 );
/* Truncate to terminating NUL in buffer if necessary */
if ( mb_cmdline_offset > sizeof ( mb_cmdlines ) )
@@ -208,8 +211,8 @@ multiboot_build_module_list ( struct image *image,
( ( count - insert ) * sizeof ( *module ) ) );
module->mod_start = start;
module->mod_end = end;
- module->string =
- multiboot_add_cmdline ( module_image->cmdline );
+ module->string = multiboot_add_cmdline ( module_image->name,
+ module_image->cmdline );
module->reserved = 0;
/* We promise to page-align modules */
@@ -264,10 +267,8 @@ static int multiboot_exec ( struct image *image ) {
memset ( &mbinfo, 0, sizeof ( mbinfo ) );
mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP |
MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
- multiboot_build_memmap ( image, &mbinfo, mbmemmap,
- ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
mb_cmdline_offset = 0;
- mbinfo.cmdline = multiboot_add_cmdline ( image->cmdline );
+ mbinfo.cmdline = multiboot_add_cmdline ( image->name, image->cmdline );
mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
mbinfo.mods_addr = virt_to_phys ( mbmodules );
@@ -279,6 +280,12 @@ static int multiboot_exec ( struct image *image ) {
*/
shutdown ( SHUTDOWN_BOOT );
+ /* Build memory map after unhiding bootloader memory regions as part of
+ * shutting everything down.
+ */
+ multiboot_build_memmap ( image, &mbinfo, mbmemmap,
+ ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
+
/* Jump to OS with flat physical addressing */
DBGC ( image, "MULTIBOOT %p starting execution at %lx\n",
image, entry );
@@ -360,6 +367,13 @@ static int multiboot_load_raw ( struct image *image,
userptr_t buffer;
int rc;
+ /* Sanity check */
+ if ( ! ( hdr->mb.flags & MB_FLAG_RAW ) ) {
+ DBGC ( image, "MULTIBOOT %p is not flagged as a raw image\n",
+ image );
+ return -EINVAL;
+ }
+
/* Verify and prepare segment */
offset = ( hdr->offset - hdr->mb.header_addr + hdr->mb.load_addr );
filesz = ( hdr->mb.load_end_addr ?
@@ -432,14 +446,14 @@ static int multiboot_load ( struct image *image ) {
return -ENOTSUP;
}
- /* Load the actual image */
- if ( hdr.mb.flags & MB_FLAG_RAW ) {
- if ( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 )
- return rc;
- } else {
- if ( ( rc = multiboot_load_elf ( image ) ) != 0 )
- return rc;
- }
+ /* There is technically a bit MB_FLAG_RAW to indicate whether
+ * this is an ELF or a raw image. In practice, grub will use
+ * the ELF header if present, and Solaris relies on this
+ * behaviour.
+ */
+ if ( ( ( rc = multiboot_load_elf ( image ) ) != 0 ) &&
+ ( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 ) )
+ return rc;
return 0;
}
diff --git a/gpxe/src/arch/i386/image/pxe_image.c b/gpxe/src/arch/i386/image/pxe_image.c
index 90550d83..63429f87 100644
--- a/gpxe/src/arch/i386/image/pxe_image.c
+++ b/gpxe/src/arch/i386/image/pxe_image.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @file
*
@@ -42,28 +44,24 @@ struct image_type pxe_image_type __image_type ( PROBE_PXE );
* @ret rc Return status code
*/
static int pxe_exec ( struct image *image ) {
+ struct net_device *netdev;
int rc;
- /* Ensure that PXE stack is ready to use */
- pxe_init_structures();
- pxe_hook_int1a();
-
/* Arbitrarily pick the most recently opened network device */
- pxe_set_netdev ( last_opened_netdev() );
-
- /* Many things will break if pxe_netdev is NULL */
- if ( ! pxe_netdev ) {
+ if ( ( netdev = last_opened_netdev() ) == NULL ) {
DBGC ( image, "IMAGE %p could not locate PXE net device\n",
image );
return -ENODEV;
}
+ /* Activate PXE */
+ pxe_activate ( netdev );
+
/* Start PXE NBP */
rc = pxe_start_nbp();
/* Deactivate PXE */
- pxe_set_netdev ( NULL );
- pxe_unhook_int1a();
+ pxe_deactivate();
return rc;
}
diff --git a/gpxe/src/arch/i386/include/basemem.h b/gpxe/src/arch/i386/include/basemem.h
index cd5668e0..c477c7fe 100644
--- a/gpxe/src/arch/i386/include/basemem.h
+++ b/gpxe/src/arch/i386/include/basemem.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <realmode.h>
#include <bios.h>
diff --git a/gpxe/src/arch/i386/include/basemem_packet.h b/gpxe/src/arch/i386/include/basemem_packet.h
index e4d4f49c..3cb47767 100644
--- a/gpxe/src/arch/i386/include/basemem_packet.h
+++ b/gpxe/src/arch/i386/include/basemem_packet.h
@@ -1,6 +1,8 @@
#ifndef BASEMEM_PACKET_H
#define BASEMEM_PACKET_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <realmode.h>
/** Maximum length of base memory packet buffer */
diff --git a/gpxe/src/arch/i386/include/bios.h b/gpxe/src/arch/i386/include/bios.h
index 979a092c..70bb73da 100644
--- a/gpxe/src/arch/i386/include/bios.h
+++ b/gpxe/src/arch/i386/include/bios.h
@@ -1,6 +1,8 @@
#ifndef BIOS_H
#define BIOS_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#define BDA_SEG 0x0040
#define BDA_FBMS 0x0013
#define BDA_NUM_DRIVES 0x0075
diff --git a/gpxe/src/arch/i386/include/biosint.h b/gpxe/src/arch/i386/include/biosint.h
index d365cf01..ab466af3 100644
--- a/gpxe/src/arch/i386/include/biosint.h
+++ b/gpxe/src/arch/i386/include/biosint.h
@@ -6,6 +6,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <realmode.h>
struct segoff;
diff --git a/gpxe/src/arch/i386/include/bits/byteswap.h b/gpxe/src/arch/i386/include/bits/byteswap.h
index 98418c29..ddbd40ed 100644
--- a/gpxe/src/arch/i386/include/bits/byteswap.h
+++ b/gpxe/src/arch/i386/include/bits/byteswap.h
@@ -1,6 +1,8 @@
#ifndef ETHERBOOT_BITS_BYTESWAP_H
#define ETHERBOOT_BITS_BYTESWAP_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
static inline __attribute__ ((always_inline, const)) uint16_t
__bswap_variable_16(uint16_t x)
{
diff --git a/gpxe/src/arch/i386/include/bits/compiler.h b/gpxe/src/arch/i386/include/bits/compiler.h
index 119a9a21..000db0c1 100644
--- a/gpxe/src/arch/i386/include/bits/compiler.h
+++ b/gpxe/src/arch/i386/include/bits/compiler.h
@@ -1,6 +1,8 @@
#ifndef _BITS_COMPILER_H
#define _BITS_COMPILER_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifndef ASSEMBLY
/** Declare a function with standard calling conventions */
diff --git a/gpxe/src/arch/i386/include/bits/endian.h b/gpxe/src/arch/i386/include/bits/endian.h
index 413e702d..84188542 100644
--- a/gpxe/src/arch/i386/include/bits/endian.h
+++ b/gpxe/src/arch/i386/include/bits/endian.h
@@ -1,6 +1,8 @@
#ifndef ETHERBOOT_BITS_ENDIAN_H
#define ETHERBOOT_BITS_ENDIAN_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif /* ETHERBOOT_BITS_ENDIAN_H */
diff --git a/gpxe/src/arch/i386/include/bits/errfile.h b/gpxe/src/arch/i386/include/bits/errfile.h
index 5ea8a318..32b8a085 100644
--- a/gpxe/src/arch/i386/include/bits/errfile.h
+++ b/gpxe/src/arch/i386/include/bits/errfile.h
@@ -1,6 +1,8 @@
#ifndef _BITS_ERRFILE_H
#define _BITS_ERRFILE_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @addtogroup errfile Error file identifiers
* @{
@@ -12,6 +14,7 @@
#define ERRFILE_bios_smbios ( ERRFILE_ARCH | ERRFILE_CORE | 0x00030000 )
#define ERRFILE_biosint ( ERRFILE_ARCH | ERRFILE_CORE | 0x00040000 )
#define ERRFILE_int13 ( ERRFILE_ARCH | ERRFILE_CORE | 0x00050000 )
+#define ERRFILE_pxeparent ( ERRFILE_ARCH | ERRFILE_CORE | 0x00060000 )
#define ERRFILE_bootsector ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_bzimage ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 )
diff --git a/gpxe/src/arch/i386/include/bits/io.h b/gpxe/src/arch/i386/include/bits/io.h
index dd0ee444..eded9778 100644
--- a/gpxe/src/arch/i386/include/bits/io.h
+++ b/gpxe/src/arch/i386/include/bits/io.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/x86_io.h>
#endif /* _BITS_IO_H */
diff --git a/gpxe/src/arch/i386/include/bits/nap.h b/gpxe/src/arch/i386/include/bits/nap.h
index f8ba7a7c..1354f6bb 100644
--- a/gpxe/src/arch/i386/include/bits/nap.h
+++ b/gpxe/src/arch/i386/include/bits/nap.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/bios_nap.h>
#include <gpxe/efi/efix86_nap.h>
diff --git a/gpxe/src/arch/i386/include/bits/smbios.h b/gpxe/src/arch/i386/include/bits/smbios.h
index 647ea19e..a68413aa 100644
--- a/gpxe/src/arch/i386/include/bits/smbios.h
+++ b/gpxe/src/arch/i386/include/bits/smbios.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/bios_smbios.h>
#endif /* _BITS_SMBIOS_H */
diff --git a/gpxe/src/arch/i386/include/bits/stdint.h b/gpxe/src/arch/i386/include/bits/stdint.h
index 6ccf0971..8edf1319 100644
--- a/gpxe/src/arch/i386/include/bits/stdint.h
+++ b/gpxe/src/arch/i386/include/bits/stdint.h
@@ -1,8 +1,10 @@
#ifndef _BITS_STDINT_H
#define _BITS_STDINT_H
-typedef unsigned int size_t;
-typedef signed int ssize_t;
+FILE_LICENCE ( GPL2_OR_LATER );
+
+typedef __SIZE_TYPE__ size_t;
+typedef signed long ssize_t;
typedef signed long off_t;
typedef unsigned char uint8_t;
diff --git a/gpxe/src/arch/i386/include/bits/timer.h b/gpxe/src/arch/i386/include/bits/timer.h
index 99666d84..32e6bd47 100644
--- a/gpxe/src/arch/i386/include/bits/timer.h
+++ b/gpxe/src/arch/i386/include/bits/timer.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/bios_timer.h>
#include <gpxe/rdtsc_timer.h>
diff --git a/gpxe/src/arch/i386/include/bits/uaccess.h b/gpxe/src/arch/i386/include/bits/uaccess.h
index 0ecc5028..2bb52e02 100644
--- a/gpxe/src/arch/i386/include/bits/uaccess.h
+++ b/gpxe/src/arch/i386/include/bits/uaccess.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <librm.h>
#endif /* _BITS_UACCESS_H */
diff --git a/gpxe/src/arch/i386/include/bits/umalloc.h b/gpxe/src/arch/i386/include/bits/umalloc.h
index dcbd0a6b..17ba2cb2 100644
--- a/gpxe/src/arch/i386/include/bits/umalloc.h
+++ b/gpxe/src/arch/i386/include/bits/umalloc.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/memtop_umalloc.h>
#endif /* _BITS_UMALLOC_H */
diff --git a/gpxe/src/arch/i386/include/bootsector.h b/gpxe/src/arch/i386/include/bootsector.h
index e9071052..8730fbfc 100644
--- a/gpxe/src/arch/i386/include/bootsector.h
+++ b/gpxe/src/arch/i386/include/bootsector.h
@@ -6,6 +6,8 @@
* x86 bootsector image format
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern int call_bootsector ( unsigned int segment, unsigned int offset,
unsigned int drive );
diff --git a/gpxe/src/arch/i386/include/bzimage.h b/gpxe/src/arch/i386/include/bzimage.h
index aee058ae..42b31fe4 100644
--- a/gpxe/src/arch/i386/include/bzimage.h
+++ b/gpxe/src/arch/i386/include/bzimage.h
@@ -1,6 +1,8 @@
#ifndef _BZIMAGE_H
#define _BZIMAGE_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/**
@@ -75,6 +77,9 @@ struct bzimage_header {
/** Offset of bzImage header within kernel image */
#define BZI_HDR_OFFSET 0x1f1
+/** bzImage boot flag value */
+#define BZI_BOOT_FLAG 0xaa55
+
/** bzImage magic signature value */
#define BZI_SIGNATURE 0x53726448
diff --git a/gpxe/src/arch/i386/include/callbacks_arch.h b/gpxe/src/arch/i386/include/callbacks_arch.h
deleted file mode 100644
index f9cba488..00000000
--- a/gpxe/src/arch/i386/include/callbacks_arch.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/* Callout/callback interface for Etherboot
- *
- * This file provides the mechanisms for making calls from Etherboot
- * to external programs and vice-versa.
- *
- * Initial version by Michael Brown <mbrown@fensystems.co.uk>, January 2004.
- *
- * $Id$
- */
-
-#ifndef CALLBACKS_ARCH_H
-#define CALLBACKS_ARCH_H
-
-/* Skip the definitions that won't make sense to the assembler */
-#ifndef ASSEMBLY
-
-/* Struct to hold general-purpose register values. PUSHAL and POPAL
- * can work directly with this structure; do not change the order of
- * registers.
- */
-typedef struct {
- union {
- uint16_t di;
- uint32_t edi;
- };
- union {
- uint16_t si;
- uint32_t esi;
- };
- union {
- uint16_t bp;
- uint32_t ebp;
- };
- union {
- uint16_t sp;
- uint32_t esp;
- };
- union {
- struct {
- uint8_t bl;
- uint8_t bh;
- } PACKED;
- uint16_t bx;
- uint32_t ebx;
- };
- union {
- struct {
- uint8_t dl;
- uint8_t dh;
- } PACKED;
- uint16_t dx;
- uint32_t edx;
- };
- union {
- struct {
- uint8_t cl;
- uint8_t ch;
- } PACKED;
- uint16_t cx;
- uint32_t ecx;
- };
- union {
- struct {
- uint8_t al;
- uint8_t ah;
- } PACKED;
- uint16_t ax;
- uint32_t eax;
- };
-} regs_t;
-
-/* Struct to hold segment register values. Don't change the order;
- * many bits of assembly code rely on it.
- */
-typedef struct {
- uint16_t cs;
- uint16_t ss;
- uint16_t ds;
- uint16_t es;
- uint16_t fs;
- uint16_t gs;
-} PACKED seg_regs_t;
-
-/* Struct for a GDT descriptor */
-typedef struct {
- uint16_t limit;
- uint32_t address;
- uint16_t padding;
-} PACKED gdt_descriptor_t;
-
-/* Struct for a GDT entry. Use GDT_SEGMENT() to fill it in.
- */
-typedef struct {
- uint16_t limit_0_15;
- uint16_t base_0_15;
- uint8_t base_16_23;
- uint8_t accessed__type__sflag__dpl__present;
- uint8_t limit_16_19__avl__size__granularity;
- uint8_t base_24_31;
-} PACKED gdt_segment_t;
-
-#define GDT_SEGMENT(base,limit,type,sflag,dpl,avl,size,granularity) \
- ( (gdt_segment_t) { \
- ( (limit) & 0xffff ), \
- ( (base) & 0xffff ), \
- ( ( (base) >> 16 ) & 0xff ), \
- ( ( 1 << 0 ) | ( (type) << 1 ) | \
- ( (sflag) << 4 ) | ( (dpl) << 5 ) | ( 1 << 7 ) ), \
- ( ( (limit) >> 16 ) | \
- ( (avl) << 4 ) | ( (size) << 5 ) | ( (granularity) << 7 ) ),\
- ( (base) >> 24 ) \
- } )
-#define GDT_SEGMENT_BASE(gdt_segment) \
- ( (gdt_segment)->base_0_15 | \
- (gdt_segment)->base_16_23 << 16 | \
- (gdt_segment)->base_24_31 << 24 )
-#define GDT_SEGMENT_LIMIT(gdt_segment) \
- ( (gdt_segment)->limit_0_15 | \
- ( ( (gdt_segment)->limit_16_19__avl__size__granularity \
- & 0xf ) << 16 ) )
-#define GDT_SEGMENT_GRANULARITY(gdt_segment) \
- ( ( (gdt_segment)->limit_16_19__avl__size__granularity \
- & 0x80 ) >> 7 )
-#define GDT_SEGMENT_TYPE(gdt_segment) \
- ( ( (gdt_segment)->accessed__type__sflag__dpl__present & 0x0e ) >> 1 )
-#define GDT_SEGMENT_SIZE(gdt_segment) \
- ( ( (gdt_segment)->limit_16_19__avl__size__granularity \
- & 0x60 ) >> 5 )
-
-#define GDT_TYPE_DATA (0x0)
-#define GDT_TYPE_STACK (0x2)
-#define GDT_TYPE_WRITEABLE (0x1)
-#define GDT_TYPE_CODE (0x6)
-#define GDT_TYPE_EXEC_ONLY_CODE (0x4)
-#define GDT_TYPE_CONFORMING (0x1)
-#define GDT_SFLAG_SYSTEM (0)
-#define GDT_SFLAG_NORMAL (1)
-#define GDT_AVL_NORMAL (0)
-#define GDT_SIZE_16BIT (0x0)
-#define GDT_SIZE_32BIT (0x2)
-#define GDT_SIZE_64BIT (0x1)
-#define GDT_SIZE_UNKNOWN (0x3)
-#define GDT_GRANULARITY_SMALL (0)
-#define GDT_GRANULARITY_LARGE (1)
-#define GDT_SEGMENT_NORMAL(base,limit,type,size,granularity) \
- GDT_SEGMENT ( base, limit, type, \
- GDT_SFLAG_NORMAL, 0, GDT_AVL_NORMAL, \
- size, granularity )
-
-/* Protected mode code segment */
-#define GDT_SEGMENT_PMCS(base) GDT_SEGMENT_NORMAL ( \
- base, 0xfffff, GDT_TYPE_CODE | GDT_TYPE_CONFORMING, \
- GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
-#define GDT_SEGMENT_PMCS_PHYS GDT_SEGMENT_PMCS(0)
-/* Protected mode data segment */
-#define GDT_SEGMENT_PMDS(base) GDT_SEGMENT_NORMAL ( \
- base, 0xfffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
- GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
-#define GDT_SEGMENT_PMDS_PHYS GDT_SEGMENT_PMDS(0)
-/* Real mode code segment */
-/* Not sure if there's any reason to use GDT_TYPE_EXEC_ONLY_CODE
- * instead of just GDT_TYPE_CODE, but that's what our old GDT did and
- * it worked, so I'm not changing it.
- */
-#define GDT_SEGMENT_RMCS(base) GDT_SEGMENT_NORMAL ( \
- base, 0xffff, GDT_TYPE_EXEC_ONLY_CODE | GDT_TYPE_CONFORMING, \
- GDT_SIZE_16BIT, GDT_GRANULARITY_SMALL )
-/* Real mode data segment */
-#define GDT_SEGMENT_RMDS(base) GDT_SEGMENT_NORMAL ( \
- base, 0xffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
- GDT_SIZE_16BIT, GDT_GRANULARITY_SMALL )
-/* Long mode code segment */
-#define GDT_SEGMENT_LMCS(base) GDT_SEGMENT_NORMAL ( \
- base, 0xfffff, GDT_TYPE_CODE | GDT_TYPE_CONFORMING, \
- GDT_SIZE_64BIT, GDT_GRANULARITY_LARGE )
-#define GDT_SEGMENT_LMCS_PHYS GDT_SEGMENT_LMCS(0)
-/* Long mode data segment */
-/* AFIACT, GDT_SIZE_64BIT applies only to code segments */
-#define GDT_SEGMENT_LMDS(base) GDT_SEGMENT_NORMAL ( \
- base, 0xfffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
- GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
-#define GDT_SEGMENT_LMDS_PHYS GDT_SEGMENT_LMDS(0)
-
-/* Template for creating GDT structures (including segment register
- * lists), suitable for passing as parameters to external_call().
- */
-#define GDT_STRUCT_t(num_segments) \
- struct { \
- gdt_descriptor_t descriptor; \
- gdt_segment_t segments[num_segments]; \
- } PACKED
-/* And utility function for filling it in */
-#define GDT_ADJUST(structure) { \
- (structure)->descriptor.address = \
- virt_to_phys(&((structure)->descriptor.limit)); \
- (structure)->descriptor.limit = \
- sizeof((structure)->segments) + 8 - 1; \
- (structure)->descriptor.padding = 0; \
-}
-
-/* Data passed in to in_call() by assembly wrapper.
- */
-typedef struct {
- regs_t regs;
- seg_regs_t seg_regs;
- gdt_descriptor_t gdt_desc;
- uint32_t flags;
- struct {
- uint32_t offset;
- uint32_t segment;
- } ret_addr;
-} PACKED i386_pm_in_call_data_t;
-
-typedef struct {
- seg_regs_t seg_regs;
- union {
- uint16_t pad;
- uint16_t prefix_sp;
- };
- uint16_t flags;
- struct {
- uint16_t offset;
- uint16_t segment;
- } ret_addr;
- uint32_t orig_opcode;
-} PACKED i386_rm_in_call_data_t;
-
-typedef struct {
- i386_pm_in_call_data_t *pm;
- i386_rm_in_call_data_t *rm;
-} i386_in_call_data_t;
-#define in_call_data_t i386_in_call_data_t
-
-/* Function prototypes
- */
-extern int install_rm_callback_interface ( void *address, size_t available );
-
-#endif /* ASSEMBLY */
-
-#define RM_IN_CALL (0)
-#define RM_IN_CALL_FAR (2)
-
-#endif /* CALLBACKS_ARCH_H */
diff --git a/gpxe/src/arch/i386/include/comboot.h b/gpxe/src/arch/i386/include/comboot.h
index 56661a80..1232f0a7 100644
--- a/gpxe/src/arch/i386/include/comboot.h
+++ b/gpxe/src/arch/i386/include/comboot.h
@@ -7,6 +7,8 @@
* SYSLINUX COMBOOT
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <setjmp.h>
#include <gpxe/in.h>
diff --git a/gpxe/src/arch/i386/include/fakee820.h b/gpxe/src/arch/i386/include/fakee820.h
index f1fe8aff..9d00fb67 100644
--- a/gpxe/src/arch/i386/include/fakee820.h
+++ b/gpxe/src/arch/i386/include/fakee820.h
@@ -1,6 +1,8 @@
#ifndef _FAKEE820_H
#define _FAKEE820_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern void fake_e820 ( void );
extern void unfake_e820 ( void );
diff --git a/gpxe/src/arch/i386/include/gpxe/abft.h b/gpxe/src/arch/i386/include/gpxe/abft.h
index 1c651ef1..9065e61a 100644
--- a/gpxe/src/arch/i386/include/gpxe/abft.h
+++ b/gpxe/src/arch/i386/include/gpxe/abft.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/acpi.h>
#include <gpxe/if_ether.h>
diff --git a/gpxe/src/arch/i386/include/gpxe/bios_nap.h b/gpxe/src/arch/i386/include/gpxe/bios_nap.h
index f1c721e9..c32429b9 100644
--- a/gpxe/src/arch/i386/include/gpxe/bios_nap.h
+++ b/gpxe/src/arch/i386/include/gpxe/bios_nap.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef NAP_PCBIOS
#define NAP_PREFIX_pcbios
#else
diff --git a/gpxe/src/arch/i386/include/gpxe/bios_smbios.h b/gpxe/src/arch/i386/include/gpxe/bios_smbios.h
index 0a6f277a..83726b11 100644
--- a/gpxe/src/arch/i386/include/gpxe/bios_smbios.h
+++ b/gpxe/src/arch/i386/include/gpxe/bios_smbios.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef SMBIOS_PCBIOS
#define SMBIOS_PREFIX_pcbios
#else
diff --git a/gpxe/src/arch/i386/include/gpxe/bios_timer.h b/gpxe/src/arch/i386/include/gpxe/bios_timer.h
index 7e3caa3c..ed9df522 100644
--- a/gpxe/src/arch/i386/include/gpxe/bios_timer.h
+++ b/gpxe/src/arch/i386/include/gpxe/bios_timer.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef TIMER_PCBIOS
#define TIMER_PREFIX_pcbios
#else
diff --git a/gpxe/src/arch/i386/include/gpxe/ibft.h b/gpxe/src/arch/i386/include/gpxe/ibft.h
index 5eef547b..c41e2e40 100644
--- a/gpxe/src/arch/i386/include/gpxe/ibft.h
+++ b/gpxe/src/arch/i386/include/gpxe/ibft.h
@@ -28,6 +28,8 @@
*
*/
+FILE_LICENCE ( BSD2 );
+
/** @file
*
* iSCSI boot firmware table
diff --git a/gpxe/src/arch/i386/include/gpxe/memtop_umalloc.h b/gpxe/src/arch/i386/include/gpxe/memtop_umalloc.h
index a3cd2c01..eaf7025b 100644
--- a/gpxe/src/arch/i386/include/gpxe/memtop_umalloc.h
+++ b/gpxe/src/arch/i386/include/gpxe/memtop_umalloc.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef UMALLOC_MEMTOP
#define UMALLOC_PREFIX_memtop
#else
diff --git a/gpxe/src/arch/i386/include/gpxe/rdtsc_timer.h b/gpxe/src/arch/i386/include/gpxe/rdtsc_timer.h
index 0e03d707..67ba22f0 100644
--- a/gpxe/src/arch/i386/include/gpxe/rdtsc_timer.h
+++ b/gpxe/src/arch/i386/include/gpxe/rdtsc_timer.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef TIMER_RDTSC
#define TIMER_PREFIX_rdtsc
#else
diff --git a/gpxe/src/arch/i386/include/gpxe/sbft.h b/gpxe/src/arch/i386/include/gpxe/sbft.h
new file mode 100644
index 00000000..30038436
--- /dev/null
+++ b/gpxe/src/arch/i386/include/gpxe/sbft